我在红宝石代码中多次看到无与伦比的File.open
呼叫
能给我举个例子吗?我只在新手编写的代码中看到过这些新手,他们缺乏 “大多数编程语言中的常识,即处理文件的流程是开放使用-关闭”。
经验丰富的Rubyist要么明确关闭文件,要么更习惯于使用的块形式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
该类定义了一个终结器来关闭文件。
如果没有,那为什么要选择呢?
因为浪费的内存很便宜,但是浪费的文件描述符却不是。因此,将文件描述符的生存期与某些内存块的生存期联系起来是没有意义的。
你根本无法预测,当垃圾收集器将运行。你甚至不能预测,如果它将运行在所有的:如果你从来没有的内存用完,垃圾收集器将永远不会运行,因此终结永远不会运行,因此该文件将永远不会被关闭。