ruby - Ruby 在哪里跟踪其打开的文件描述符?

标签 ruby file-io io file-descriptor filehandle

这个问题不是关于什么

这个问题不是关于如何使用 File#close 或 File#open block 语法自动关闭文件。这是一个关于 Ruby 在运行时将其打开的文件描述符列表存储在何处的问题。

实际问题

如果您有一个带有打开描述符的程序,但您无权访问相关的文件或 IO 对象,您如何才能找到对当前打开的文件描述符的引用?举个例子:

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

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

但是,被丢弃的文件对象并没有消失;它只是无法以任何明显的方式访问。在对象完成之前,Ruby 必须在某个地方跟踪它……但是在哪里?

最佳答案

TL;博士

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

回答

ObjectSpace类说:

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.

我是如何测试的

我在 Ruby 1.9.3p194 的控制台上对此进行了测试。

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

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

然后我探索了与 File 对象交互的不同方式,即使我没有使用显式对象引用。一旦我了解了 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}

结论

可能还有其他方法可以做到这一点,但这是我想出的解决办法。如果您知道更好的方法,请发布另一个答案。世界将因此而变得更美好。

关于ruby - Ruby 在哪里跟踪其打开的文件描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10922045/

相关文章:

java - 如何写入 Java 中的 txt 文件中的特定行号

c - 快速读取大于c中内存的文件

c - 在读取未知行长度的文件时确定 EOF

java - Java 中的 PrintWriter 给出意外行为

ruby - sinatra 停止从公用文件夹加载文件

ruby - Sinatra 的 `put` 是如何工作的?

ruby - Geokit LatLng 两点之间的中点

ruby-on-rails - Discourse 插件 - 发送电子邮件

java - java中文件路径的Windows转义序列问题

java - FileOutputStream.flush() 能否保证其他进程能够一致读取文件内容?