【问题标题】:File.open, open and IO.foreach in Ruby, what is the difference?Ruby中的file.open、open和IO.foreach,有什么区别?
【发布时间】:2009-11-13 05:00:15
【问题描述】:

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

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

【问题讨论】:

    标签: ruby file-io


    【解决方案1】:

    这 3 个选项之间存在重要差异。

    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/
    

    在第二种情况下,Kernel#open 返回的StringIO 对象实际上包含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​​ 文档的工具。你在你的 shell 上像这样使用它。

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

    有了它,您几乎可以找到我在这里写的所有内容以及更多内容。

    【讨论】:

    • 感谢指向 ri 的指针。不过,它可能会更友好。 “ri File.open”没有为我找到任何东西。试图找到“open”,我最终找到了 Kernel#orig_open,然后尝试查找“Kernel#open”,结果却被告知有多个匹配项,而没有任何明显的方法可以给我提供完全 Kernel#open 的文档,而不是搜索 Kernel #打开*。
    • 如果你将一个block传递给File.open,它会在block终止时自动关闭,无需调用IO#close
    • File 是 IO 的子类,因此如果您想让文件更自文档化,您可以使用 File.foreach 而不是 IO.foreach。请注意 File.read().each 将整个文件加载到内存中。如果您正在处理大文件,这可能是不可取的。我会坚持使用 File.foreach。
    • 感谢您的 RI 提示。这东西太有用了。
    • File.read("file").each { |line| puts line } 似乎并非在所有情况下都有效,因为它无法逐行处理。我失败的例子是一个带有\r\n 行尾的纯文本文件。
    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 2010-11-17
    • 2010-12-16
    • 2013-06-10
    相关资源
    最近更新 更多