是 fs。Dir 最终在超出范围时发布

Is fs.Dir eventually released when out of scope

提问人:Sinder 提问时间:11/16/2023 更新时间:11/16/2023 访问量:21

问:

我从另一个问题中了解到,操作系统的文件句柄永远不会自动释放,即使是垃圾收集器;代码如下:fs.FileHandle

const file = await fs.open(path);
// do something with file
await file.close();

如果在不关闭文件的情况下对文件执行某些操作时反复发生错误,则最终会导致应用程序崩溃。EMFILE: too many open files

注意:答案来自2016年。7年后是否仍然适用?

我的问题是,同样的事情也适用吗?fs.Dir

const dir = await fs.opendir(path);

for await (let entry of dir) {
    // do something with entry
}

在这里,应该在异步迭代器到达末尾时自动关闭(如本问题NodeJS fs 源代码所示)。dir

如果在此期间发生错误,它是否也永远不会关闭?// do something with entry

节点 .js 文件句柄

评论

0赞 Mike 'Pomax' Kamermans 11/16/2023
它应该,因为你仍然只是创建一个显式的文件/流句柄 - 但是,绝大多数时候你不应该需要这两个函数中的任何一个,你只想分别使用和获取文件和目录内容。fs.readFilefs.readdir

答:

1赞 jfriend00 11/16/2023 #1

fs.Dir将在迭代结束时“self”关闭(例如,当迭代器完成时)。for/of

但是,如果你不让迭代器走到最后,你将不得不调用对象。关于这一点的文档在这里.close()fs.Dir

Nodejs 当前不会在垃圾收集时关闭系统资源。他们可能正在努力在未来能够做到这一点(通过在 GC 系统中添加一些钩子),但这不是现在发生的事情。您必须使用一些更高级别的函数,该函数会在操作完成时自动为您关闭系统资源(例如,流可能会使用文件句柄),或者您必须手动确保为该资源调用适当的方法来释放它,例如在所有代码路径中。.close()

如果期间发生错误,它也不会被关闭 如果在期间发生错误,它也永远不会被关闭 // 对条目做一些事情?

由你来捕获在你自己处理迭代时发生的错误,并在错误发生后继续迭代器,允许它完成迭代,然后自动关闭,或者如果你提前中止迭代,则必须手动调用。.close()fs.Dir

垃圾回收不会为你调用操作系统句柄上的关闭。

评论

0赞 Bergi 11/16/2023
"通过在 GC 系统中添加一些钩子“——钩子已经存在了,只需要使用它们FinalizationRegistry
0赞 jfriend00 11/16/2023
@Bergi - 是的,这就是我的观点。钩子就在那里。但是,使用它们来清理系统资源的代码尚不存在。