错误写入文件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
事件已经发射)。
如果你想确保所有的数据已经被刷新到输出文件,你可以在fsStream
上fsStream
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();