tor*_*gen 12 javascript file-io node.js
我正在尝试为Node.js实现一个例程,该例程允许一个人打开一个文件,此时正被其他一些进程附加,然后在附加到文件时立即返回数据块.它可以被认为与tail -fUNIX命令类似,但是当块可用时立即执行,而不是轮询一段时间内的更改.或者,人们可以将其视为与使用套接字一样处理文件 - 期望on('data')在文件明确关闭之前不时触发.
在C land中,如果我要实现它,我只需打开文件,将其文件描述符提供给select()(或任何具有类似名称的替代函数),然后只读取块,因为文件描述符标记为"可读".因此,当没有任何东西需要阅读时,它将无法读取,并且当某些内容被附加到文件时,它再次可读.
我有点期望在Javascript中跟踪代码示例的这种行为:
function readThatFile(filename) {
const stream = fs.createReadStream(filename, {
flags: 'r',
encoding: 'utf8',
autoClose: false // I thought this would prevent file closing on EOF too
});
stream.on('error', function(err) {
// handle error
});
stream.on('open', function(fd) {
// save fd, so I can close it later
});
stream.on('data', function(chunk) {
// process chunk
// fs.close() if I no longer need this file
});
}
Run Code Online (Sandbox Code Playgroud)
但是,这个代码示例只在遇到EOF时才会失效,所以我不能等待新的块到达.当然,我可以使用fs.open和重新实现这一点fs.read,但这有点失败的Node.js目的.或者,我可以fs.watch()申请更改,但它不能通过网络工作,我不喜欢一直重新打开文件的想法,而不仅仅是保持打开.
我试过这样做:
const fd = fs.openSync(filename, 'r'); // sync for readability' sake
const stream = net.Socket({ fd: fd, readable: true, writable: false });
Run Code Online (Sandbox Code Playgroud)
但没有运气 - net.Socket不开心和抛出TypeError: Unsupported fd type: FILE.
那么,任何解决方案?
所以,五年来人们似乎仍在寻找这个问题的答案,但目前还没有答案。
简而言之:你不能。尤其是在 Node.js 中,你根本做不到。
长答案:这没什么原因。
首先,POSIX 标准对这方面的行为进行了如下澄清:select()
与常规文件关联的文件描述符应始终为准备读取、准备写入和错误条件选择 true。
因此,select()无法帮助检测超出文件末尾的写入。
与之poll()类似的是:
常规文件在读取和写入时应始终轮询 TRUE。
我不能确定epoll(),因为它不是标准化的,你必须阅读相当长的实现,但我认为它是相似的。
由于 Node.js 实现的核心 libuv 使用和read(),在pread()preadv()uv__fs_read()文件末尾调用时它们都不会阻塞,因此当遇到 EOF 时它总是返回空缓冲区。所以,这里也没有运气。
所以,总结一下,如果需要这样的功能,那么您的设计一定有问题,您应该修改它。