【问题标题】:How can track write progress when piping with Node.js?使用 Node.js 管道时如何跟踪写入进度?
【发布时间】:2019-07-09 01:33:56
【问题描述】:

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

我最初的想法是在发出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 管道时如何跟踪 write 进度?

【问题讨论】:

  • 如果它为他的线程添加了任何有意义的值,您可能需要查看 node.js 缓冲区

标签: javascript node.js progress-bar


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您可以手动进行管道,并使用来自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)}%)`);
        });
    });
    

    【讨论】:

    • 我之前尝试过类似的事情,但所有数据都保存在内存中,这会导致应用程序因大文件而崩溃。这就是我使用管道的原因。这不会将数据保存在内存中吗?
    • 这应该有最小的内存使用,如果有疑问,您可以在事件循环中添加process.memoryUsage()并监控内存使用情况。
    【解决方案3】:

    不知何故,我记得这个线程是关于内存效率的,无论如何,我已经编写了一个小脚本,它非常节省内存并且可以很好地跟踪进度。我在一个 230MB 的文件下对其进行了测试,结果不言而喻。 https://gist.github.com/J-Cake/78ce059972595823243526e022e327e4

    我使用的示例文件有点奇怪,因为它报告的 content-length 标头实际上已关闭,但程序使用的内存不超过 4.5 MiB。

    【讨论】:

      猜你喜欢
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多