Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve a file in Ruby

Tags:

file

io

ruby

So what I am trying to do is pass a file name into a method and and check if the file is closed. What I am struggling to do is getting a file object from the file name without actually opening the file.

def file_is_closed(file_name)
  file = # The method I am looking for
  file.closed?
end

I have to fill in the commented part. I tried using the load_file method from the YAML module but I think that gives the content of the file instead of the actual file.

I couldn't find a method in the File module to call. Is there a method maybe that I don't know?

like image 314
eytanfb Avatar asked Mar 16 '26 23:03

eytanfb


1 Answers

File#closed? returns whether that particular File object is closed, so there is no method that is going to make your current attempted solution work:

f1 = File.new("test.file")
f2 = File.new("test.file")
f1.close
f1.closed? # => true # Even though f2 still has the same file open

It would be best to retain the File object that you're using in order to ask it if it is closed, if possible.

If you really want to know if your current Ruby process has any File objects open for a particular path, something like this feels hack-ish but should mostly work:

def file_is_closed?(file_name)
  ObjectSpace.each_object(File) do |f|
    if File.absolute_path(f) == File.absolute_path(file_name) && !f.closed?
      return false
    end
  end

  true
end

I don't stand by that handling corner cases well, but it seems to work for me in general:

f1 = File.new("test.file")
f2 = File.new("test.file")
file_is_closed?("test.file") # => false
f1.close
file_is_closed?("test.file") # => false
f2.close
file_is_closed?("test.file") # => true

If you want to know if any process has the file open, I think you'll need to resort to something external like lsof.

like image 142
Darshan Rivka Whittle Avatar answered Mar 19 '26 02:03

Darshan Rivka Whittle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!