Ruby在哪里跟踪其打开的文件描述符? [英] Where does Ruby keep track of its open file descriptors?

查看:161
本文介绍了Ruby在哪里跟踪其打开的文件描述符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是什么 关于



这个问题是关于如何自动关闭文件的 与文件#关闭或文件#打开块语法。这是一个关于Ruby在运行时存储打开文件描述符列表的问题。



实际问题



你有一个打开描述符的程序,但你没有访问相关的文件或IO对象,你怎么能找到一个对当前打开的文件描述符的引用?以这个例子为例:

  filename ='/ tmp / foo'
%x(touch#{filename} )
File.open(filename)
filehandle = File.open(filename)

打开第一个File实例,但对象的引用不存储在变量中。第二个实例存储在 filehandle 中,我可以用#inspect或#close轻松访问它。



然而,丢弃的File对象isn走了;它只是无法以任何明显的方式访问。直到对象完成后,Ruby必须在某个地方跟踪它...但是在哪里呢?

DR

所有File和IO对象都存储在ObjectSpace中。

Answer



ObjectSpace 类说:


$ b


ObjectSpace模块包含许多与垃圾收集工具交互的例程,并允许您用迭代器遍历所有活动对象。




我如何测试这个



我在Ruby 1.9.3p194的控制台上测试了这个。



测试夹具非常简单。这个想法是有两个文件对象具有不同的对象标识,但只有一个可以通过变量直接访问。另一个是在某处。

 #不要保存对第一个对象的引用。 
文件名='/ tmp / foo'
File.open(文件名)
filehandle = File.open(文件名)

然后,我研究了不同的方法,即使我没有使用显式对象引用,也可以与File对象进行交互。一旦我知道了ObjectSpace,这一点非常容易。

 #列出所有打开的File对象。 
ObjectSpace.each_object(File)do | f |
放置%s:%d%[f.path,f.fileno]除非f.closed?
end

#列出我们没有存储在变量中的danglingFile对象。
ObjectSpace.each_object(File)do | f |
除非f.closed?
printf%s:%d \ n,f.path,f.fileno除非f ===文件句柄
结束
结束

#关闭任何悬挂文件对象。忽略已经关闭的文件,并把
#单独保存在* filehandle *中的accessible对象。
ObjectSpace.each_object(File){| f | f.close除非f === filehandle rescue nil}



结论



也许还有其他的方法可以做到这一点,但是这是我想出来的一个办法来抓我自己的痒。如果你知道更好的方法,请张贴另一个答案。世界将是一个更好的地方。


What This Question Is Not About

This question is not about how to auto-close a file with File#close or the File#open block syntax. It's a question about where Ruby stores its list of open file descriptors at runtime.

The Actual Question

If you have a program with open descriptors, but you don't have access to the related File or IO object, how can you find a reference to the currently-open file descriptors? Take this example:

filename='/tmp/foo'
%x( touch "#{filename}" )
File.open(filename)
filehandle = File.open(filename)

The first File instance is opened, but the reference to the object is not stored in a variable. The second instance is stored in filehandle, where I can easily access it with #inspect or #close.

However, the discarded File object isn't gone; it's just not accessible in any obvious way. Until the object is finalized, Ruby must be keeping track of it somewhere...but where?

解决方案

TL; DR

All File and IO objects are stored in ObjectSpace.

Answer

The ObjectSpace class says:

The ObjectSpace module contains a number of routines that interact with the garbage collection facility and allow you to traverse all living objects with an iterator.

How I Tested This

I tested this at the console on Ruby 1.9.3p194.

The test fixture is really simple. The idea is to have two File objects with different object identities, but only one is directly accessible through a variable. The other is "out there somewhere."

# Don't save a reference to the first object.
filename='/tmp/foo'
File.open(filename)
filehandle = File.open(filename)

I then explored different ways I could interact with the File objects even if I didn't use an explicit object reference. This was surprisingly easy once I knew about ObjectSpace.

# List all open File objects.
ObjectSpace.each_object(File) do |f|
  puts "%s: %d" % [f.path, f.fileno] unless f.closed?
end

# List the "dangling" File object which we didn't store in a variable.
ObjectSpace.each_object(File) do |f|
  unless f.closed?  
    printf "%s: %d\n", f.path, f.fileno unless f === filehandle
  end
end

# Close any dangling File objects. Ignore already-closed files, and leave
# the "accessible" object stored in *filehandle* alone.
ObjectSpace.each_object(File) {|f| f.close unless f === filehandle rescue nil}

Conclusion

There may be other ways to do this, but this is the answer I came up with to scratch my own itch. If you know a better way, please post another answer. The world will be a better place for it.

这篇关于Ruby在哪里跟踪其打开的文件描述符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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