【问题标题】:NodeJS streams: WritableStream output is zero bytes or non-zero bytes inconsistentlyNodeJS流:WritableStream输出是零字节或非零字节不一致
【发布时间】:2020-07-22 07:29:27
【问题描述】:

我在使用 NodeJS 流时遇到了一个奇怪的错误。

问题描述:

如果我运行这个 node.js 脚本,最终文件 (final_x.txt) 有时为零字节,有时是正确的输出(即 input_x.txt 的内容)。不一致。

const fs = require('fs');
const { pipeline } = require('stream');

(() => {
    function testStreamPipingWithFS() {
        var input = fs.createReadStream('./input_x.txt', {autoClose: true});
        var output = fs.createWriteStream('./output_x.txt', {autoClose: true});
        
        pipeline(input, output, (err) => {
            if(err)
                console.log(err);
        });

        var intermediate = fs.createReadStream('./output_x.txt', {autoClose: true});
        var finalFile = './final_x.txt';
        var final = fs.createWriteStream(finalFile, {autoClose: true});
        
        pipeline(intermediate, final, (err) => {
            if(err)
                console.log(err);
        });
    }

    console.log(process.versions);
    testStreamPipingWithFS();

})();

环境:

Windows 版本为Microsoft Windows [Version 10.0.18363.959]

脚本记录的 process.versions 显示如下:

{
  node: '12.18.2',
  v8: '7.8.279.23-node.39',
  uv: '1.38.0',
  zlib: '1.2.11',
  brotli: '1.0.7',
  ares: '1.16.0',
  modules: '72',
  nghttp2: '1.41.0',
  napi: '6',
  llhttp: '2.0.4',
  http_parser: '2.9.3',
  openssl: '1.1.1g',
  cldr: '37.0',
  icu: '67.1',
  tz: '2019c',
  unicode: '13.0'
}

我错过了什么?任何帮助表示赞赏。谢谢。

【问题讨论】:

    标签: node.js


    【解决方案1】:

    因为pipeline是异步的,所以需要将第二次调用pipeline放在第一次调用pipeline的回调中:

        function testStreamPipingWithFS() {
            
            var input = fs.createReadStream('./input_x.txt', {autoClose: true});
            var output = fs.createWriteStream('./output_x.txt', {autoClose: true});
            
            pipeline(input, output, (err) => {
                if(err)
                    console.log(err);
                else {
                    var intermediate = fs.createReadStream('./output_x.txt', {autoClose: true});
                    var finalFile = './final_x.txt';
                    var final = fs.createWriteStream(finalFile, {autoClose: true});
                    
                    pipeline(intermediate, final, (err) => {
                    if(err)
                        console.log(err);
                    });
                }
            })
        }
    
        testStreamPipingWithFS();
    

    如果您不将第二次调用放在回调中,则无法保证对管道的第一次调用会在第二次调用管道运行之前完成,因此您将得到不可预测的结果。

    【讨论】:

    • 谢谢你,@crosen9999。那讲得通。我接受了你的回答。
    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多