В большинстве языков программирования общеизвестно, что процесс работы с файлами открыт-используется-закрывается. Тем не менее, я много раз видел в кодах Ruby непревзойденные вызовы File.open, и, более того, я нашел эту жемчужину знаний в документации ruby:
Потоки ввода-вывода автоматически закрываются, когда они запрашиваются сборщиком мусора.
darkredandyellow дружелюбный irc:
[17:12] да, а также количество файловых дескрипторов обычно ограничено ОС
[17:29] Я предполагаю, что вы можете легко исчерпать доступные файловые дескрипторы, прежде чем сборщик мусора очистит вверх. в этом случае вы можете захотеть использовать их самостоятельно. "заявлено сборщиком мусора". означает, что сборщик мусора действует в какой-то момент в будущем. и это дорого. множество причин для явного закрытия файлов.
- Нужно ли явно закрывать
- Если да, то почему ГХ автоматически закрывается?
- Если нет, то почему вариант?
$ ulimit -n => 1024
он высокий только тогда, когда вы выполняете простую работу. Плохая привычка однажды вызовет большие проблемы!Ответы:
Вы можете привести пример? Я только когда-либо видел это в коде, написанном новичками, которым не хватает «общих знаний о большинстве языков программирования, что поток для работы с файлами открыт-использует-закрывает».
Опытные рубисты либо явно закрывают свои файлы, либо, что более идиоматично, используют блочную форму
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
Скрипты - особый случай. Сценарии обычно работают так быстро и используют так мало файловых дескрипторов, что их просто не имеет смысла закрывать, поскольку операционная система все равно закроет их при выходе из сценария.
Да.
Потому что после того, как он собрал объект, у вас больше нет возможности закрыть файл, и, таким образом, вы получите утечку файловых дескрипторов.
Обратите внимание, что файлы закрывает не сборщик мусора. Сборщик мусора просто выполняет любые финализаторы для объекта, прежде чем он его соберет. Так уж получилось, что
File
класс определяет финализатор, который закрывает файл.Потому что потраченная впустую память - это дешево, а потраченные впустую файловые дескрипторы - нет. Следовательно, не имеет смысла связывать время жизни файлового дескриптора со временем жизни некоторого фрагмента памяти.
Вы просто не можете предсказать, когда запустится сборщик мусора. Вы даже не можете предсказать , запустится ли он вообще : если у вас никогда не закончится память, сборщик мусора никогда не запустится, поэтому финализатор никогда не запустится, поэтому файл никогда не будет закрыт.
источник
ensure
,rescue
а вraise
них нет необходимости.ensure
обойтисьrescue
. И вы не можете просто молча проглотить исключение, вам нужно распространить его на вызывающую программу после закрытия файла. В любом случае, напомните мне еще раз в мае '15 :-DВы всегда должны закрывать файловые дескрипторы после использования, это также очистит его. Часто люди используют File.open или аналогичный метод с блоками для обработки времени жизни файлового дескриптора. Например:
File.open('foo', 'w') do |f| f.write "bar" end
В этом примере файл закрывается автоматически.
источник
Согласно http://ruby-doc.org/core-2.1.4/File.html#method-c-open
Следовательно, будет автоматически закрываться, когда блок завершается : D
источник
источник
Мы можем использовать
File.read()
функцию для чтения файла в рубине ..... например,file_variable = File.read("filename.txt")
в этом примере
file_variable
может иметь полное значение этого файла ....источник