Ruby的File.open以及对f.close的需要?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (22)

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

I / O流在被垃圾回收器声明时会自动关闭。

  • 我们是否需要明确关闭?
  • 如果是,那么GC为什么会自动关闭?
  • 如果没有,那么为什么选择?
提问于
用户回答回答于

我只看到,在由新手写的代码因为缺少了大多数编程语言常识,处理文件流是open-use-close

有经验的Rubyists要么明确地关闭他们的文件,要么更习惯地使用块的形式File.open,它会自动为你关闭文件。它的实现基本如下所示:

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

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

我们是否需要明确关闭?

是。

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

因为在收集完对象之后,再也无法关闭该文件,因此会泄漏文件描述符。

请注意,它不是关闭文件的垃圾收集器。垃圾收集器只是在收集对象之前执行任何对象的终结器。恰好碰巧File类定义了一个关闭文件的终结器。

如果没有,那么为什么选择?

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

用户回答回答于

该始终关闭文件描述符。人们经常用打开文件或具有处理文件描述符生存期的块的等效方法。例如:

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

在该示例中,文件将自动关闭。

扫码关注云+社区