错误写入文件fsstreamNodeJS

目的

使用csv-write-stream和fsstream将一个非常大的数组写入文件。

背景

我有一个小型应用程序,它将大量数据(数千个条目)写入CSV文件。 为了达到这个目的,我使用前面提到的库,这只不过是fsstream的一个掩码(一个方便)。 但是,应用程序在运行时崩溃,我不知道为什么。

错误

文件被创build并且stream开始写入,但是在执行期间我总是有同样的错误:

events.js:141 throw er; // Unhandled 'error' event ^ Error: write after end at writeAfterEnd (_stream_writable.js:166:12) at WriteStream.Writable.write (_stream_writable.js:211:5) at ondata (_stream_readable.js:536:20) at emitOne (events.js:77:13) at emit (events.js:169:7) at Readable.read (_stream_readable.js:368:10) at flow (_stream_readable.js:751:26) at WriteStream.<anonymous> (_stream_readable.js:609:7) at emitNone (events.js:67:13) at WriteStream.emit (events.js:166:7) 

我知道这个错误是与这段代码有关的:

 let writer = csvWriter({ headers: ['country', 'postalCode'] }); let fsStream = fs.createWriteStream('output.csv'); writer.pipe(fsStream); //very big array ! currCountryCodes = [{country: 'A', postalCode: 0}, {country: 'B', postalCode: 1 }]; for (let j = 0; j < currCountryCodes.length; j++) { writer.write(currCountryCodes[j]); } writer.end(function() { fsStream.end(function() { console.log('=== CSV written successfully, stopping application ==='); process.exit(); }); }); 

最具体的执行:

 fsStream.end(function() { console.log('=== CSV written successfully, stopping application ==='); process.exit(); }); 

但我不明白为什么会发生。 不知何故,它只发生在我写的数组有成千上万行的时候,如果我只有十几个,它运行得很好。

从阅读错误,我得到的印象是,我仍然在closuresstream后写入文件,但不能发生,因为这些function只运行时,一切都刷新到文件(右?)

  • 我的代码有什么问题?

问题是你(可以理解)认为writer.end()的callbackwriter.end()被调用的时候,没有数据会被写入到fsStream ,而不是这种情况(如错误所示)。

writer是一个双工stream ,这意味着它是可读和可写的。 通过调用.end()方法,你告诉它,你不会再写信给它了。 但是,这并不意味着它仍然不可读。

当您随后结束fsStream ,仍然可能会有某些缓冲区中的未fsStream数据fsStream送到fsStream ,从而产生错误。

你可以通过监听writer上的end事件来解决这个问题,这是一个可读的信号,没有数据可以被读取:

 writer.end(function() { writer.on('end', function() { fsStream.end(function() { console.log('=== CSV written successfully, stopping application ==='); process.exit(); }); }); }); 

编辑 :我认为, writer.end()被调用时, fsStream也会自动结束(所以fsStream.end()是多余的,它的callback可能不会被调用,因为finish事件已经发射)。

如果你想确保所有的数据已经被刷新到输出文件,你可以在fsStreamfsStream finish事件:

 writer.end(function() { fsStream.on('finish', function() { console.log('=== CSV written successfully, stopping application ==='); process.exit(); }); }); 

甚至:

 fsStream.on('finish', function() { console.log('=== CSV written successfully, stopping application ==='); process.exit(); }); writer.end();