Ruby's File.open и необходимость в f.close - PullRequest
82 голосов
/ 25 января 2011

В большинстве языков программирования общеизвестно, что процесс работы с файлами открыт для использования и закрытия.Тем не менее, я много раз видел в кодах ruby ​​непревзойденные вызовы File.open, и, кроме того, я нашел этот камень знаний в документах ruby:

потоки ввода / вывода автоматически закрываются,они утверждаются сборщиком мусора.

darkredandyellow дружественный irc по этому вопросу:
[17:12] да, а также число файловых дескрипторовобычно ограничивается ОС
[17:29] Я предполагаю, что вы можете легко исчерпать доступные файловые дескрипторы до того, как очиститель мусора очистится.в этом случае вы можете использовать их самостоятельно."заявлено сборщиком мусора."означает, что GC действует в какой-то момент в будущем.и это дорогомножество причин явного закрытия файлов.

  1. Нужно ли нам явно закрывать
  2. Если да, то почему GC автоматически закрывается?
  3. Если нет, то почемувариант?

Ответы [ 5 ]

121 голосов
/ 25 января 2011

Я много раз видел в рубиновых кодах не совпадающих File.open звонки

Можете привести пример? Я только когда-либо видел, что в коде, написанном новичками, которым не хватает , "в большинстве языков программирования" общеизвестно, что поток для работы с файлами открыт-используется-закрыт ".

Опытные Rubyists либо явно закрывают свои файлы, либо, иными словами, используют блочную форму File.open, которая автоматически закрывает файл для вас. Его реализация в основном выглядит примерно так:

def File.open(*args, &block)
  return open_with_block(*args, &block) if block_given?
  open_without_block(*args)
end

def File.open_without_block(*args)
  # do whatever ...
end

def File.open_with_block(*args)
  yield f = open_without_block(*args)
ensure
  f.close
end

Скрипты - это особый случай. Сценарии обычно выполняются настолько короткими и используют так мало файловых дескрипторов, что закрывать их просто не имеет смысла, так как операционная система все равно закроет их при выходе из сценария.

Нам нужно явно закрыть?

Да.

Если да, то почему GC автоматически закрывается?

Поскольку после того, как он соберет объект, у вас больше не будет возможности закрыть файл, и, таким образом, вы потеряете дескрипторы файлов.

Обратите внимание, что не сборщик мусора закрывает файлы. Сборщик мусора просто выполняет любые финализаторы для объекта перед тем, как его собрать. Так уж получилось, что класс File определяет финализатор, который закрывает файл.

Если нет, то почему опция?

Потому что потраченная впустую память дешева, а дескрипторы потраченных файлов - нет. Следовательно, не имеет смысла связывать время жизни файлового дескриптора с временем жизни некоторого куска памяти.

Вы просто не можете предсказать , когда запустит сборщик мусора. Вы даже не можете предсказать , если вообще запустится : если у вас никогда не кончится память, сборщик мусора никогда не запустится, поэтому финализатор никогда не запустится, поэтому файл никогда не будет быть закрытым.

67 голосов
/ 25 января 2011

Вы должны всегда закрывать файловые дескрипторы после использования, это также очистит его. Часто люди используют File.open или эквивалентный метод с блоками для обработки времени жизни дескриптора файла. Например:

File.open('foo', 'w') do |f|
    f.write "bar"
end

В этом примере файл закрывается автоматически.

1 голос
/ 26 мая 2016

Согласно http://ruby -doc.org / core-2.1.4 / File.html # method-c-open

Без связанного блока File.open является синонимом :: new. Если указывается необязательный блок кода, в качестве аргумента передается открытый файл и объект File будет автоматически закрыт, когда блок завершается. Значение блока будет возвращено из File.open.

Следовательно, автоматически закроется, когда завершится блок : D

1 голос
/ 25 января 2011
  1. Да
  2. В случае, если вы этого не сделаете, или если есть какой-либо другой сбой
  3. См. 2.
0 голосов
/ 10 января 2015

Мы можем использовать функцию File.read() для чтения файла в ruby ​​..... например,

file_variable = File.read("index.html")

в этом примере file_variable может иметь полное значение этого файла ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...