【发布时间】: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}
【问题讨论】:
以下所有 API 都做同样的事情:打开一个文件并为每一行调用一个块。有什么偏好我们应该使用一个而不是另一个?
File.open("file").each_line {|line| puts line}
open("file").each_line {|line| puts line}
IO.foreach("file") {|line | puts line}
【问题讨论】:
这 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 相比,这清楚地表明您正在处理一个文件。在这种情况下失败:
s= File.read("/dev/zero") # => never terminates
s.each …
ri 是一个向您展示 ruby 文档的工具。你在你的 shell 上像这样使用它。
ri File.open
ri open
ri IO.foreach
ri File#each_line
有了它,您几乎可以找到我在这里写的所有内容以及更多内容。
【讨论】:
File.open,它会在block终止时自动关闭,无需调用IO#close
File.read("file").each { |line| puts line } 似乎并非在所有情况下都有效,因为它无法逐行处理。我失败的例子是一个带有\r\n 行尾的纯文本文件。