Lua: закрытие файла обязательно? - PullRequest
1 голос
/ 17 октября 2019

Допустим, я хочу сохранить содержимое 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

Ответы [ 2 ]

3 голосов
/ 18 октября 2019

Lua закроет файлы, когда файловый объект будет собран сборщиком мусора - как сказал Personage в своем ответе.

Однако это может быть не скоро . Если вы не закрываете файлы самостоятельно, то:

  • Если вы продолжаете открывать файлы, вы можете столкнуться с максимальным количеством открытых файлов, прежде чем они будут закрыты автоматически.
  • В некоторыхплатформы, другие процессы могут не иметь возможности открыть файл для записи, пока он открыт для чтения.
  • Если вы откроете файл для записи, данные, которые вы пишете, могут фактически не сохраняться в файле до тех пор, покаон закрывается.
  • Поскольку сборка мусора связана с использованием memory , который не имеет никакого отношения к файлам, файл может долго не закрываться, если вы не выделяете многопамять.
1 голос
/ 18 октября 2019

Lua FILE* - дескриптор ресурса, аналогичный std::ifstream или std::ofstream в C ++. Дескрипторы ресурсов предназначены для автоматического выделения и последующего освобождения ресурсов - фундаментальная концепция объектно-ориентированного программирования.

Lua FILE* s имеет 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 вызывается вместо функции по умолчанию. Это означает, что «Файл закрыт» печатается в stderr при выходе из сценария.

Итак, чтобы вернуться к исходному вопросу, нет необходимости явно закрывать файлы Lua.

...