使用 Node.js 进行管道传输时如何跟踪写入进度?

JBi*_*Bis 6 javascript node.js progress-bar

我正在尝试跟踪从读取流到写入流的管道的进度,以便我可以向用户显示进度。

我最初的想法是在事件发出时跟踪进度,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);
Run Code Online (Sandbox Code Playgroud)

然而我意识到仅仅因为它被阅读,并不意味着它实际上是被写的。如果删除了,就可以看到这一点pipe,因为data事件仍然会发出。

使用 Node.js 进行管道传输时如何跟踪写入进度?

zeo*_*dtr 7

您可以像这样使用虚拟转换流:

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)
            ...
    }
);
Run Code Online (Sandbox Code Playgroud)


Nev*_*ver 3

您可以手动进行管道操作,并使用callbackfrom writable.write()

callback: <function> 当这块数据被刷新时的回调

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)}%)`);
    });
});
Run Code Online (Sandbox Code Playgroud)