Node.js - 使用多个流正确关闭 fd

Node.js - Properly closing fd with multiple streams

我正在创建一个 append/rw 文件(取决于下载是否恢复)

this.syncFile = await fs.promises.open(this.syncPath, 'a+');
this.syncFile = await fs.promises.open(this.syncPath, 'r+');

稍后我为该 FD 创建一个写入流

let writeStream = fs.createWriteStream(null, {fd:this.syncFile.fd, autoClose:false, highWaterMark: 1024*1024});

下载剩余数据后,我可能会也可能不会为同一个 FD 创建一个 readStream 来计算完整文件的校验和

let readStream = fs.createReadStream(null, {fd:this.syncFile.fd, autoClose:false, highWaterMark: 1024*1024, start:0});

为了完成,我想关闭 FD。

fs.closeSync(this.syncFile.fd);

我在 readStream/writeStream 上尝试了多种与 close() 或 dispose() 的组合 我不断收到未捕获的异常

[Window Title]
Error
[Content]
Uncaught Exception:
Error: EBADF: Closing file descriptor 5 on garbage collection failed, close

或关于关闭 gc 上的文件描述符的控制台警告 总是连续两个有时后面跟着

Error: EBADF: bad file descriptor, write

为什么会这样? read/write 流有选项 autoClose:true 另外,以前,当我只有一个 writeStream 时,一些我无法重新创建的组合起作用了。

在这种情况下关闭所有流和FD的正确方法是什么? 我等不及 GC 关闭文件描述符,因为它持有文件的独占锁,我正在更改其属性的文件 (child_process.execSync('attrib -h +r "' + this.finalPath + '"');) 在触发 GC 之前,其他程序也无法使用该文件。

如果我只做

delete this.syncFile; 我收到了

的漂亮垃圾邮件
(node:25180) Warning: Closing file descriptor 10 on garbage collection
(node:25180) Warning: Closing file descriptor 10 on garbage collection
(node:25180) Warning: Closing file descriptor 8 on garbage collection
(node:25180) Warning: Closing file descriptor 8 on garbage collection
(node:25180) Warning: Closing file descriptor 7 on garbage collection
(node:25180) Warning: Closing file descriptor 7 on garbage collection
(node:25180) Warning: Closing file descriptor 9 on garbage collection
(node:25180) Warning: Closing file descriptor 9 on garbage collection

但没有异常,处理或其他方式,但由于上面列出的问题,这仍然不够好。我唯一的选择似乎是强制执行 GC 收集?

如果您使用 fs.promises.open() 打开文件,那么您将获得更新的 FileHandle 对象(不是常规文件描述符),您将需要对该对象调用 close 作为在 fileHandle.close() 中,而不是 fs.close(fd).