File.open, open и IO.foreach в Ruby, в чем разница? - PullRequest
50 голосов
/ 13 ноября 2009

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

File.open("file").each_line {|line| puts line}
open("file").each_line {|line| puts line}   
IO.foreach("file") {|line | puts line}

1 Ответ

82 голосов
/ 13 ноября 2009

Между этими тремя вариантами есть важные различия.

File.open("file").each_line { |line| puts line }

  • File.open открывает локальный файл и возвращает объект файла
  • файл остается открытым, пока вы не наберете IO#close для него

open("file").each_line { |line| puts line }

Kernel.open смотрит на строку, чтобы решить, что с ней делать.

open(".irbrc").class # => File
open("http://google.com/").class # => StringIO
File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/

Во втором случае объект StringIO, возвращаемый Kernel#open, фактически содержит содержимое http://google.com/. Если Kernel#open возвращает объект File, он остается открытым, пока вы не вызовете IO#close .

IO.foreach("file") { |line| puts line }

  • IO.foreach открывает файл, вызывает указанный блок для каждой прочитанной строки и затем закрывает файл.
  • Вам не нужно беспокоиться о закрытии файла.

File.read("file").each { |line| puts line }

Вы не упомянули этот выбор, но я бы использовал его в большинстве случаев.

  • File.read полностью читает файл и возвращает его в виде строки.
  • Вам не нужно беспокоиться о закрытии файла.
  • По сравнению с IO.foreach ясно, что вы имеете дело с файлом.
  • Сложность памяти для этого O (n). Если вы знаете, что имеете дело с небольшим файлом, это не является недостатком. Но если это может быть большой файл, и вы знаете, что ваша память может быть меньше, чем O (n), не используйте этот выбор.

Сбой в этой ситуации:

 s= File.read("/dev/zero") # => never terminates
 s.each …

п

ri - это инструмент, который показывает вам документацию по ruby. Вы используете это как на своей оболочке.

ri File.open
ri open
ri IO.foreach
ri File#each_line

С этим вы можете найти почти все, что я написал здесь и многое другое.

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