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

时间:2019-07-09 01:33:56

标签: 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);

但是我意识到仅仅是因为它被读取,并不意味着它实际上是被写入的。如果pipe事件仍然发出,则可以删除data

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

3 个答案:

答案 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)
            ...
    }
);