Ruby的File.open和f.close的需要

在大多数编程语言中,用于处理文件的stream程是open-close-close。 然而,我在ruby代码中看到了很多次无与伦比的File.open调用,而且我在ruby文档中发现了这些宝贵的知识 :

当垃圾收集器声明时,I / Ostream会自动closures。

darkredandyellow友好irc采取的问题:
[17:12]是的,而且文件描述符的数量通常受OS的限制
[17:29]我认为在垃圾收集器清理之前 ,你可以很容易地用完可用的文件描述符。 在这种情况下,您可能想要自己closures它们。 “垃圾收集者声称。” 意味着GC在未来的某个时刻起作用。 而且很贵。 很多明确closures文件的原因。

  1. 我们是否需要明确closures?
  2. 如果是,那GC为什么会自动closures?
  3. 如果没有,那么为什么select?

我在ruby代码中看到很多次无与伦比的File.open调用

你能举个例子吗? 我只能看到,在缺乏 “在大多数编程语言中使用文件的stream程是开放使用closures的常识”的新手编写的代码中。

有经验的Rubyists要么明确地closures他们的文件,要么更习惯地使用File.open的块forms,它将自动closures文件。 它的实现基本如下所示:

 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 

脚本是一个特例。 脚本通常运行的很短,并且使用如此之less的文件描述符,以至于无法closures它们,因为当脚本退出时,操作系统将会closures它们。

我们需要明确closures吗?

是。

如果是,那GC为什么会自动closures?

因为在收集完这个对象后,你再也不能closures这个文件了,这样你就会泄露文件描述符。

请注意,这不是closures文件的垃圾收集器。 垃圾收集器只是在收集对象之前执行任何对象的终结器。 File类定义了一个closures文件的终结器。

如果没有,那么为什么select?

因为浪费的内存很便宜,但是浪费的文件描述符却不是。 因此,将文件描述符的生存期与某些内存块的生命周期联系起来是没有意义的。

你根本无法预测垃圾收集器何时运行。 你甚至不能预测它是否会运行:如果你永远不会运行内存,垃圾收集器将永远不会运行,因此终结器将永远不会运行,因此该文件将永远不会closures。

你应该总是在使用后closures文件描述符,这也将刷新它。 通常人们使用File.open或等效的方法来处理文件描述符的生命周期。 例如:

 File.open('foo', 'w') do |f| f.write "bar" end 

在那个例子中,文件自动closures。

  1. 如果你不这样做,或者如果有其他的失败
  2. 见2。

我们可以使用File.read()函数来读取ruby中的文件…..例如,

 file_variable = File.read("index.html") 

在这个例子中, file_variable可以具有该文件的全部值。

根据http://ruby-doc.org/core-2.1.4/File.html#method-c-open

没有关联的块,File.open是:: new的同义词。 如果给出了可选的代码块,则会将打开的文件作为parameter passing,当块终止时,File对象将自动closures。 该块的值将从File.open返回。

因此, 块终止时将自动closures :D