英文:
Why does `stream.read()` or `stream.once('readable')` kill the process without an error?
问题
当我尝试使用 readable.read()
和 readable.once('redable')
时,我偶然发现一个奇怪的问题。似乎其中一个会在没有任何错误的情况下终止我的Node.js进程。
我本来希望以下代码会抛出一个错误或者无限期挂起:
const { createReadStream } = require('fs');
process.on('unhandledRejection', error => {
console.log(error)
});
process.on('error', e => {
console.log('error', e)
});
process.on('exit', e => {
console.log('exit', e)
});
(async () => {
// test.txt 是一个空文件
const stream = createReadStream('test.txt', { encoding: 'utf-8' })
const waitForReadable = () => new Promise(r => stream.once('readable', r))
for (let i = 0; i < 1000; i += 1) {
console.log(i)
stream.read()
await waitForReadable()
}
})()
但实际上,它的输出是:
0
1
exit 0
英文:
While experimenting with readable.read()
and readable.once('redable')
I stumbled upon a peculiar problem. Seems like one of the abote kills my node.js process without any error.
I would expect that the following code will throw an error or will hang indefinitely
const { createReadStream } = require('fs');
process.on('unhandledRejection', error => {
console.log(error)
});
process.on('error', e => {
console.log('error', e)
});
process.on('exit', e => {
console.log('exit', e)
});
(async () => {
// test.txt is an empty file
const stream = createReadStream('test.txt', { encoding: 'utf-8' })
const waitForReadable = () => new Promise(r => stream.once('readable', r))
for (let i = 0; i < 1000; i += 1) {
console.log(i)
stream.read()
await waitForReadable()
}
})()
But instead, it outputs:
0
1
exit 0
答案1
得分: 1
createReadStream
的行为是,在触发end
事件后,它会关闭流并且到达文件末尾。据我所知,没有办法覆盖这个行为。
autoClose
似乎可以处理这个问题,但实际上不行。这是文档中唯一描述这一行为的部分。
如果
autoClose
设置为false
,那么文件描述符不会关闭,即使出现错误也不会关闭。关闭文件描述符并确保没有文件描述符泄漏是应用程序的责任。如果autoClose
设置为true
(默认行为),在error
或end
时文件描述符将自动关闭。
一旦触发end
事件并且所有事件订阅者取消订阅,事件循环将被清除,Node.js会自动终止。
如果您想要实现类似"tail"的体验,您需要使用fs.watchFile
。
英文:
The way createReadStream
behaves is that it closes the stream once it reaches the end-of-file after it fires the end
event. There is no way to override this behavior as far as I could find.
autoClose
seems like it might handle it, but it does not. This is the only part of the documentation that describes this behavior.
> If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is the application's responsibility to close it and make sure there's no file descriptor leak. If autoClose is set to true (default behavior), on 'error' or 'end' the file descriptor will be closed automatically.
Once the end
event is fired and all event subscribers unsubscribe, the event-loop is cleared and Node.js terminates itself.
If you're looking to have a tail-like experience, you will need to go through fs.watchFile
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论