我正在尝试将NodeJS中处理的文本文件流式传输到浏览器。以下是处理之前的文本文件。该文件名为dbUsers.json。
{"userId":443,"email":"[email protected]","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439821109,"deleted":false}
{"userId":447,"email":"[email protected]","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439909013,"deleted":false}
{"userId":451,"email":"[email protected]","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567443638340,"deleted":false}
...
处理后,我可以使用以下命令将数据流式传输到NodeJS服务器上的新文件:
// Create a writable stream and specify the file which will receive the data from the readable stream.
let destinationStream = fs.createWriteStream(_data.baseDir + '/dbPermissions/dbUsers' + '/' + 'test' + '.txt', {flags : 'a'});
pipeline
(
sourceStream,
destinationStream,
function(error){if(error){console.log('There was an error.');}}
);
新文件显示按预期处理的数据。一些字段已被删除,标记为删除的记录也已删除。这表明sourceStream在起作用。现在,新文件中的数据如下:
{"userId":443,"email":"[email protected]","timeStamp":1567439821109}
{"userId":447,"email":"[email protected]","timeStamp":1567439909013}
{"userId":451,"email":"[email protected]","timeStamp":1567443638340}
...
在将SourceStream流传输到客户端浏览器之前,将它记录到NodeJS控制台会产生以下输出。
Readable {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: [Object], tail: [Object], length: 45 },
length: 3035,
pipes:
WriteStream {
_writableState: [WritableState],
writable: true,
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
path:
'C:\\Users\\user\\Desktop\\Tutorials\\iotajs\\ias\\accounting\\/dbPermissions/dbUsers/test.txt',
fd: null,
flags: 'a',
mode: 438,
start: undefined,
autoClose: true,
pos: undefined,
bytesWritten: 0,
closed: false },
pipesCount: 1,
flowing: true,
ended: true,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: true,
readableListening: false,
resumeScheduled: true,
paused: false,
emitClose: true,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: true,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
[Object: null prototype] {
close: [ [Function], [Function: onclose] ],
end: [ [Function: onend], [Function] ],
finish: [Function: onfinish],
error: [Function: onerror],
data: [Function: ondata] },
_eventsCount: 5,
_maxListeners: undefined }
Returning this response: 200
Returning this response: 200
[将sourceStream流传输到浏览器,然后将responseTextStream记录到浏览器的控制台时,输出与上面相同。因此,我确信sourceStream会使用新名称responseTextStream完整地到达客户端。
我需要使用的数据可能已锁定在上面对象的buffer属性,现在在上面称为responseTextStream客户端浏览器。
我的问题是我不知道如何访问缓冲区,我也不知道如何将其从数字转换回文本。
以下是我希望的客户端浏览器中的功能使用缓冲区中的数据。这是我需要帮助的地方-我不知道如何访问信息流。谢谢,约翰
// Populate the dbUsersList webpage with user records.
app.loadUsersListPage = function()
{
// Ask the server for the JSON records found in the dbUsers file.
// Then run the callback function defined here which inserts rows into the usersListTable on the webpage
// and populates them with data from the file of JSON records returned.
app.client.request(undefined,'api/aUsers','GET',QueryStringObject,undefined,function(statusCode,responseTextStream)
{
// if the call to handlers._users.get which is mapped to api/aUsers called back success.
if(statusCode == 200)
{
// The streamed data can be seen on the console as a buffer full of numbers
console.log(responseTextStream._readableState.buffer.head.data.data);
// Create a handle which can be used to manipulate the table on the webpage.
var table = document.getElementById("usersListTable");
// The pseudocode below does not work but is shows what I hope to accomplish.
// The line below does not help to access the stream. This is where I need help.
// What line or lines of code would facilitate access to the stream and allow
// processing it as a string, character by character, as shown below.
var Astr = responseTextStream;
var line = "";
for(var i=0; i<Astr.length; i++)
{
var chr = String.fromCharCode(Astr[i]);
if(chr == "\n" || chr == "\r")
{
// Look at each line of json at the console as it is consumed.
console.log("line: ",line);
// Turn the line, which is a json string, back into a json object
var recordObject = JSON.parse(line);
if(recordObject)
{
// Insert a new row in the table.
var tr = table.insertRow(-1);
// Make the new row a member of the class 'checkRow'
tr.classList.add('checkRow');
// Insert five new cells into the new row.
var td0 = tr.insertCell(0);
var td1 = tr.insertCell(1);
var td2 = tr.insertCell(2);
var td3 = tr.insertCell(3);
// load the new cells with data from the recordObject.
td0.innerHTML = recordObject.userId;
td1.innerHTML = recordObject.email;
td2.innerHTML = recordObject.timeStamp;
td3.innerHTML = '<a href="/users/edit?email=' + recordObject.userId + '">View / Edit / Delete</a>';
} // End of: if(recordObject)
// clear the line buffer to start the next line.
line = "";
} // End of: if(chr == "\n" || chr == "\r"){do stuff}
else
{
line += chr;
}
}; // End of: for(var i=0; i<Astr.length; i++){...}
} // End of: if the call to handlers._users.get which is mapped to api/aUsers called back successfully.
}); // End of: app.client.request(undefined,'api/checks','GET'...
} // End of: app.loadUsersListPage = function(){...}
// End of: Populate the dbUsersList webpage with user records.
由于您使用的是Chrome,因此您可以在一个漂亮的管道中使用所有新功能,例如TextDecoderStream和TransformStream,该管道可以从HTTP响应中流式传输数据,并以行分隔的JSON进行解码。检查一下:
const fetchPromise = fetch(url, params).then((res) => {
// Verify that we have some sort of 2xx response that we can use
if (!res.ok) {
throw res;
}
// If no content, immediately resolve, don't try to parse JSON
if (res.status === 204) {
return;
}
let textBuffer = '';
const self = this;
return res.body
// Decode as UTF-8 Text
.pipeThrough(new TextDecoderStream())
// Split on lines
.pipeThrough(new TransformStream({
transform(chunk, controller) {
textBuffer += chunk;
const lines = textBuffer.split('\n');
for (const line of lines.slice(0, -1)) {
controller.enqueue(line);
}
textBuffer = lines.slice(-1)[0];
},
flush(controller) {
if (textBuffer) {
controller.enqueue(textBuffer);
}
}
}))
// Parse JSON objects
.pipeThrough(new TransformStream({
transform(line, controller) {
if (line) {
controller.enqueue(
JSON.parse(line)
);
}
}
}));
});
现在,您可以像其他任何对象一样使用此新对象流:
const res = await fetchPromise;
const reader = res.getReader();
function read() {
reader.read().then(({value, done}) => {
if (value) {
// Your object will be here
}
if (done) {
return;
}
read();
});
}
read();
((注意:我尚未在此示例上下文中测试此代码...我从一个项目中对其进行了修改,因此请仔细研究并使其适合您的特定目的。)