在Ruby中使用File.open,open和IO.foreach,有什么区别?

时间:2009-11-13 05:00:15

标签: ruby file-io

所有以下API都做同样的事情:打开一个文件并为每一行调用一个块。是否有任何偏好我们应该使用一个而不是另一个?

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

1 个答案:

答案 0 :(得分:81)

这三种选择之间存在重要差异。

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

ri是一个向您显示ruby文档的工具。你可以在shell上使用它。

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

有了这个,你几乎可以找到我在这里写的所有东西。