我正在使用FS#createReadStream
方法读取文件,然后使用#pipe()
方法将其传递给某些可写流。像这样:
const stream = fs.createReadStream(...);
const transformedStream = imgStream.pipe(someTransformer).pipe(anotherTransfomer);
// do something with transformedStream
在#createReadStream()
方法的文档中,我发现it has autoClose
参数默认设置为true
。
另一方面,我发现了in documentation of #pipe()
method:
一个重要的警告是,如果可读流发出错误 在处理过程中,可写目标未关闭 自动。如果发生错误,则需要手动执行 关闭每个流以防止内存泄漏。
所以我有两个问题:
我应该在Node JS中关闭可读写的流吗? (手动,使用try-finally
块)。或者流自动关闭?
或者我应该仅在我使用#pipe()
方法时才关闭流? (因为#pipe()
会导致内存泄漏)
答案 0 :(得分:4)
如果您正在使用管道事件,则可以使用unpipe结束它。
下面是使用pipe()和unpipe()事件的示例。
const writer = getWritableStreamSomehow();
const reader = getReadableStreamSomehow();
writer.on('unpipe', (src) => {
console.error('Something has stopped piping into the writer.');
assert.equal(src, reader);
});
reader.pipe(writer);
reader.unpipe(writer);
根据node.js documentation,当在可读流上调用stream.unpipe()方法时,会发出'unpipe'事件,从其目标集中删除此Writable。
为了专门解答您的问题,以下是我的想法:
1)我应该在Node JS中关闭可读写的流吗? (手动,使用try-finally块)。或者溪流关闭 自动?
2)或者我应该只关闭流,只有当我使用#pipe()时 方法? (因为#pipe()会导致内存泄漏)
无论您是否使用竖线(),都必须关闭您的流。 (如果仅使用pipe(),我也不同意你关于内存泄漏问题的评论)
此外,您无法在传统的javascript try()catch()finally()子句中关闭您的流。原因是因为读写流是异步执行的。相反,你必须为他们发出结束事件。
示例:
var readStream = getReadableStreamSomehow();
readStream
.on('data', function (chunk) {
console.log(chunk);
})
.on('end', function () {
console.log('All the data in the file has been read');
})
.on('close', function (err) {
console.log('Stream has been Closed');
});
您可以为可写流发出相同的事件。