Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 以4k块读取expressjs请求正文_Node.js_Express - Fatal编程技术网

Node.js 以4k块读取expressjs请求正文

Node.js 以4k块读取expressjs请求正文,node.js,express,Node.js,Express,我有一个ExpressJS端点,它需要获取一个请求主体,并将其划分为连续的4k字节块或页面(每4k字节对齐一次),然后对每个块执行不同的操作。因为这是二进制数据,所以需要格外小心,这样就不会有任何unicode或其他解释 我的第一个想法是这样的: req.on("data", chunk => { // do something here }) req.on("readable", () => { var chunk

我有一个ExpressJS端点,它需要获取一个请求主体,并将其划分为连续的4k字节块或页面(每4k字节对齐一次),然后对每个块执行不同的操作。因为这是二进制数据,所以需要格外小心,这样就不会有任何unicode或其他解释

我的第一个想法是这样的:

req.on("data", chunk => {
    // do something here
})
req.on("readable", () => {
    var chunk
    while (null !== (chunk = req.read(4096))) {
        // do something here
    }
})
但“在这里做点什么”必须是,“获取数据块中任意大小的数据,以4k为增量进行处理,并保留<4k的数据,以便将下一个数据块附加到其中。当我运行一个测试时,我看到接收到的第一个数据块略低于32k字节,因此实际上,对于每个请求,我都会有乱序字节的开销,以便得到4k字节对齐的数据块

我的第二个想法是这样做:

req.on("data", chunk => {
    // do something here
})
req.on("readable", () => {
    var chunk
    while (null !== (chunk = req.read(4096))) {
        // do something here
    }
})
在这种情况下,“在这里做点什么”是类似的,但由于我一次只能阅读4k,理论上我应该少做一些工作。在我运行的一个测试中,我发现在最后一次读取之前,每次读取都会返回4k,而最后一次读取的返回值不到4k。如果总是这样,我就不必存储4k页面的一部分,然后再附加页面的其余部分,这将是理想的情况,但我不知道read()是否总能很好地提供这一数量

我不确定我是否也在尝试重新发明轮子,是否已经有一种机制(非同步地)总是在不需要重新组装部分块的情况下完成下一个4k


执行此操作的最佳实践是什么?

数据
事件到达时,您可以将数据累积到范围更大的缓冲区变量中,并且当您有4k或更多时,分解出4k块并处理它:

const dataSizeToProcess = 1024 * 4;    // 4k
let accumulatedData;

req.on('data', chunk => {
    // accumulate this chunk of data
    if (!accumulatedData) {
        // first chunk of data
        accumulatedData= chunk;         
    } else {
        // add this chunk to the existing buffer
        accumulatedData= Buffer.concat([accumulatedData, chunk]);
    }
    // process as many whole chunks as we have in the accumulatedData
    while (accumulatedData.length >= dataSizeToProcess) {
        // get a whole chunk into its own buffer from the start
        const piece = accumulatedData.slice(0, dataSizeToProcess);

        // make accumulatedData be the rest of the data
        accumulatedData = accumulatedData.slice(dataSizeToProcess);

        // now process the data in the piece buffer
        
    }
});

req.on('end', () => {
    // process the last bit of data in accumulatedData
});
“阅读”的文档说明:

可选大小参数指定要读取的特定字节数。如果无法读取大小字节,则将返回null,除非流已结束,在这种情况下,将返回内部缓冲区中剩余的所有数据


这样可以确保您要么读取整个4k,要么在文件末尾读取剩余的内容。因此,没有必要做更复杂的事情。

我只是回去阅读“阅读”的文档,我想这可能没有必要<代码>可选大小参数指定要读取的特定字节数。如果无法读取大小字节,则除非流已结束,否则将返回null,在这种情况下,将返回内部缓冲区中剩余的所有数据。因此,我认为这在很大程度上保证了它可以用于我的目的。@Michael-是的,其他方法也应该可以。