Node.js 以4k块读取expressjs请求正文
我有一个ExpressJS端点,它需要获取一个请求主体,并将其划分为连续的4k字节块或页面(每4k字节对齐一次),然后对每个块执行不同的操作。因为这是二进制数据,所以需要格外小心,这样就不会有任何unicode或其他解释 我的第一个想法是这样的: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
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-是的,其他方法也应该可以。