Lua:文件关闭是否必要?

假设我想要将“passwd”文件的内容存储到变量中,就像这样:

local passwd = io.open('/etc/passwd', 'r'):read('a')

我读完文件后没有关闭它可以吗?我应该像这样重新写:

local f = io.open('/etc/passwd', 'r')
local passwd = f:read('a')
f:close()

我知道第一段代码可以运行,但我不知道它是否会引起一些隐藏的问题。

我正在使用Lua 5.3

点赞
用户9922866
用户9922866

Lua 中的 FILE* 是类似于 C++ 中的 std::ifstreamstd::ofstream 的资源句柄。资源句柄的作用是自动分配和释放资源,这是面向对象编程的基本概念。

Lua FILE* 在其 metatable 中有 close 函数,这就是你在示例中使用的 f:close()。这是为了明确地关闭它们。但是,按照面向对象编程风格,它们是用 __gc 元方法隐式关闭的。这里是我快速编写的一个示例来测试它:

function myclose(self)
    io.close(self)
    io.stderr:write(string.format("File closed\n"))
    return
end

file = assert(io.open("input.txt", "r"))
debug.getmetatable(file)["__gc"] = myclose

在最后一行,我将 __gc 的值更改为 myclose;因此,当这个 FILE* 对象的生命周期结束时,会调用 myclose 而不是默认的函数。这意味着当脚本退出时,"File closed" 将被打印到 stderr

因此,回到你最初的问题,显式关闭 Lua 文件是不必要的。

2019-10-18 00:26:07
用户106104
用户106104

Lua 会在文件对象被垃圾回收时关闭文件,正如 Personage 在他们的答案中所说。

但是,这可能不会很 _快_。如果您不自己关闭文件,则:

  • 如果您不断打开文件,则在自动关闭它们之前,您可能会遇到最大打开文件数的限制。
  • 在某些平台上,当您以读模式打开文件时,其他进程可能无法以写模式打开该文件。
  • 如果您以写模式打开文件,则写入的数据可能直到关闭文件之前才实际存储在文件中。
  • 由于垃圾回收与_内存_使用相关,与文件无关,如果您不分配太多内存,则文件可能需要很长时间才会关闭。
2019-10-18 08:55:31