我正在尝试跟踪从读取流到写入流的管道进度,以便可以向用户显示进度。
我最初的想法是在发出data
事件时跟踪进度,如下所示:
const fs = require('fs');
let final = fs.createWriteStream('output');
fs.createReadStream('file')
.on('close', () => {
console.log('done');
})
.on('error', (err) => {
console.error(err);
})
.on('data', (data) => {
console.log("data");
/* Calculate progress */
})
.pipe(final);
但是我意识到仅仅是因为它被读取,并不意味着它实际上是被写入的。如果pipe
事件仍然发出,则可以删除data
。
使用Node.js进行管道传输时,如何跟踪写入进度?
答案 0 :(得分:0)
您可以手动进行配管,并利用writable.write()中的callback
callback
:<函数>刷新此数据块时的回调
const fs = require('fs');
let from_file = `<from_file>`;
let to_file = '<to_file>';
let from_stream = fs.createReadStream(from_file);
let to_stream = fs.createWriteStream(to_file);
// get total size of the file
let { size } = fs.statSync(from_file);
let written = 0;
from_stream.on('data', data => {
// do the piping manually here.
to_stream.write(data, () => {
written += data.length;
console.log(`written ${written} of ${size} bytes (${(written/size*100).toFixed(2)}%)`);
});
});
答案 1 :(得分:0)
无论如何,我还记得该线程与内存效率有关,无论如何,我已经编写了一个非常高效的内存并很好地跟踪进度的小脚本。我在230MB的文件下对其进行了测试,结果不言而喻。 https://gist.github.com/J-Cake/78ce059972595823243526e022e327e4
我使用的示例文件有点奇怪,因为它报告的content-length
标头实际上已经关闭,但是程序使用的内存不超过4.5 MiB。
答案 2 :(得分:0)
您可以像这样使用虚拟的 Transform 流:
const stream = require('stream');
let totalBytes = 0;
stream.pipeline(
fs.createReadStream(from_file),
new stream.Transform({
transform(chunk, encoding, callback) {
totalBytes += chunk.length;
console.log(totalBytes);
this.push(chunk);
callback();
}
}),
fs.createWriteStream(to_file),
err => {
if (err)
...
}
);