Lua: 文件关闭是强制性的吗?

Lua: Is File Closing Mandatory?

假设我想将 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

A Lua FILE* 是类似于 C++ 中的 std::ifstreamstd::ofstream 的资源句柄。资源句柄旨在自动分配和释放资源——面向对象编程中的一个基本概念。

Lua FILE*s 在它们的元表中有 close 函数,这就是您在示例中使用 f:close() 调用的函数。这是明确关闭它们。但是,在 OOP 风格中,它们使用 __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 个文件。

Lua 将在垃圾收集文件对象时关闭文件 - 正如 Personage 在他们的回答中所说。

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

  • 如果您一直打开文件,您可能 运行 达到打开文件的最大数量后自动关闭。
  • 在某些平台上,其他进程可能无法打开文件进行写入,而您打开文件进行读取。
  • 如果您打开一个文件进行写入,您写入的数据在文件关闭之前可能不会真正存储在该文件中。
  • 由于垃圾收集与内存使用有关,与文件无关,如果不分配太多内存,文件可能会长时间关闭.