当引用由不同的对象持有时如何确保文件关闭 [英] How to ensure files are closed when reference is held by a different object

查看:38
本文介绍了当引用由不同的对象持有时如何确保文件关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Ruby 中,当对打开文件的引用传递给另一个对象时,如下面的代码所示,我是否需要将另一个对象引用包装在begin/ensure" 块,以确保非托管资源被关闭,还是有其他方法?

In Ruby, when the reference to an open file is handed to another object, as in the following code, do I need to wrap the other object reference in a "begin/ensure" block, to ensure the unmanaged resources get closed, or is there another way?

@doc = Nokogiri::XML(File.open("shows.xml"))

@doc.xpath("//character")
# => ["<character>Al Bundy</character>",
#    "<character>Bud Bundy</character>",
#    "<character>Marcy Darcy</character>",
#    "<character>Larry Appleton</character>",
#    "<character>Balki Bartokomous</character>",
#    "<character>John "Hannibal" Smith</character>",
#    "<character>Templeton "Face" Peck</character>",
#    "<character>"B.A." Baracus</character>",
#    "<character>"Howling Mad" Murdock</character>"]

推荐答案

一般来说,不用担心打开单个文件是可以的,如果没有其他东西会尝试写入它,并且您的程序不是长时间运行的应用程序.Ruby 将在关闭和退出时关闭该文件.(我怀疑如果操作系统看到文件已打开,它也会这样做,但如果不进入低级调试器或深入研究操作系统代码,就很难测试.)

In general, it's OK to not worry about leaving a single file open, if nothing else will be attempting to write to it, and your program isn't a long-running application. Ruby will close the file as it shuts down and exits. (I suspect the OS will do it too if it sees the file is open, but that'd be hard to test without going into a low-level debugger or digging into the OS's code.)

如果您对此感到担心,我建议您使用 File.open 的块形式,因为它会在您的代码退出块时自动关闭文件:

If you're worried about it though, I'd recommend using the block form of File.open because it automatically closes the file when your code exits the block:

require 'nokogiri'

doc = ''
File.open('./test.html', 'r') do |fi|
  doc = Nokogiri::HTML(fi)
end

puts doc.to_html

<小时>

因为我很好奇并且一直想知道,所以我做了一个小测试.我将一些 HTML 保存到一个名为test.html"的文件中并在 IRB 中运行:


Because I was curious and have always wondered, I ran a little test. I saved some HTML to a file called "test.html" and ran this in IRB:

test.rb(main):001:0> require 'nokogiri'
=> true
test.rb(main):002:0> page = File.open('test.html', 'r')
=> #<File:test.html>
test.rb(main):003:0> page.eof?
=> false
test.rb(main):004:0> page.closed?
=> false
test.rb(main):005:0> doc = Nokogiri::HTML(page)
=> #<Nokogiri::HTML::Document:0x3fc10149bc98 name="document" children=[#<Nokogiri::XML::DTD:0x3fc10149b6f8 name="html">, #<Nokogiri::XML::Element:0x3fc10149ef60 name="html" children=[#<Nokogiri::XML::Element:0x3fc10149ed58 name="head" children=[#<Nokogiri::XML::Element:0x3fc10149eb50 name="title" children=[#<Nokogiri::XML::Text:0x3fc10149e948 "Example Domain">]>, #<Nokogiri::XML::Element:0x3fc10149e740 name="meta" attributes=[#<Nokogiri::XML::Attr:0x3fc10149e6dc name="charset" value="utf-8">]>, #<Nokogiri::XML::Element:0x3fc10149e218 name="meta" attributes=[#<Nokogiri::XML::Attr:0x3fc10149e1b4 name="http-equiv" value="Content-type">, #<Nokogiri::XML::Attr:0x3fc10149e1a0 name="content" value="text/html; charset=utf-8">]>, #<Nokogiri::XML::Element:0x3fc10149da98 name="meta" attributes=[#<Nokogiri::XML::Attr:0x3fc10149da34 name="name" value="viewport">, #<Nokogiri::XML::Attr:0x3fc10149da20 name="content" value="width=device-width, initial-scale=1">]>, #<Nokogiri::XML::Element:0x3fc10149d318 name="style" attributes=[#<Nokogiri::XML::Attr:0x3fc10149d2b4 name="type" value="text/css">] children=[#<Nokogiri::XML::CDATA:0x3fc1014a0dd8 "\n\tbody {\n\t\tbackground-color: #f0f0f2;\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tfont-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\n\t}\n\tdiv {\n\t\twidth: 600px;\n\t\tmargin: 5em auto;\n\t\tpadding: 3em;\n\t\tbackground-color: #fff;\n\t\tborder-radius: 1em;\n\t}\n\ta:link, a:visited {\n\t\tcolor: #38488f;\n\t\ttext-decoration: none;\n\t}\n\t@media (max-width: 600px) {\n\t\tbody {\n\t\t\tbackground-color: #fff;\n\t\t}\n\t\tdiv {\n\t\t\twidth: auto;\n\t\t\tmargin: 0 auto;\n\t\t\tborder-radius: 0;\n\t\t\tpadding: 1em;\n\t\t}\n\t}\n\t">]>]>, #<Nokogiri::XML::Element:0x3fc1014a0aa4 name="body" children=[#<Nokogiri::XML::Text:0x3fc1014a089c "\n">, #<Nokogiri::XML::Element:0x3fc1014a07c0 name="div" children=[#<Nokogiri::XML::Text:0x3fc1014a05b8 "\n\t">, #<Nokogiri::XML::Element:0x3fc1014a04dc name="h1" children=[#<Nokogiri::XML::Text:0x3fc1014a02d4 "Example Domain">]>, #<Nokogiri::XML::Text:0x3fc1014a00cc "\n\t">, #<Nokogiri::XML::Element:0x3fc10149fff0 name="p" children=[#<Nokogiri::XML::Text:0x3fc10149fde8 "This domain is established to be used for illustrative examples in documents. You do not need to\n\t\tcoordinate or ask for permission to use this domain in examples, and it is not available for\n\t\tregistration.">]>, #<Nokogiri::XML::Text:0x3fc10149fbe0 "\n\t">, #<Nokogiri::XML::Element:0x3fc10149fb04 name="p" children=[#<Nokogiri::XML::Element:0x3fc10149f8fc name="a" attributes=[#<Nokogiri::XML::Attr:0x3fc10149f898 name="href" value="http://www.iana.org/domains/special">] children=[#<Nokogiri::XML::Text:0x3fc10149f3d4 "More information...">]>]>, #<Nokogiri::XML::Text:0x3fc1014a309c "\n">]>, #<Nokogiri::XML::Text:0x3fc1014a2e94 "\n">]>]>]>
test.rb(main):006:0> page.eof?
=> true
test.rb(main):007:0> page.closed?
=> false
test.rb(main):008:0> page.close
=> nil
test.rb(main):009:0> page.closed?
=> true

因此,换句话说,Nokogiri 不会关闭打开的文件.

So, in other words, Nokogiri does not close open files.

这篇关于当引用由不同的对象持有时如何确保文件关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆