Where does Ruby keep track of its open file descriptors?

后端 未结 1 1287
春和景丽
春和景丽 2021-02-05 05:59

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 a

1条回答
  •  借酒劲吻你
    2021-02-05 06:35

    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.

    0 讨论(0)
提交回复
热议问题