What Are the Ruby File.Open Modes and Options

What are the Ruby File.open modes and options?

In Ruby IO module documentation, I suppose.

Mode |  Meaning
-----+--------------------------------------------------------
"r" | Read-only, starts at beginning of file (default mode).
-----+--------------------------------------------------------
"r+" | Read-write, starts at beginning of file.
-----+--------------------------------------------------------
"w" | Write-only, truncates existing file
| to zero length or creates a new file for writing.
-----+--------------------------------------------------------
"w+" | Read-write, truncates existing file to zero length
| or creates a new file for reading and writing.
-----+--------------------------------------------------------
"a" | Write-only, starts at end of file if file exists,
| otherwise creates a new file for writing.
-----+--------------------------------------------------------
"a+" | Read-write, starts at end of file if file exists,
| otherwise creates a new file for reading and
| writing.
-----+--------------------------------------------------------
"b" | Binary file mode (may appear with
| any of the key letters listed above).
| Suppresses EOL <-> CRLF conversion on Windows. And
| sets external encoding to ASCII-8BIT unless explicitly
| specified.
-----+--------------------------------------------------------
"t" | Text file mode (may appear with
| any of the key letters listed above except "b").

File opening mode in Ruby

The file open modes are not really specific to ruby - they are part of IEEE Std 1003.1 (Single UNIX Specification). You can read more about it here:

http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html

r or rb
Open file for reading.

w or wb
Truncate to zero length or create file for writing.

a or ab
Append; open or create file for writing at end-of-file.

r+ or rb+ or r+b
Open file for update (reading and writing).

w+ or wb+ or w+b
Truncate to zero length or create file for update.

a+ or ab+ or a+b
Append; open or create file for update, writing at end-of-file.

Any mode that contains the letter 'b' stands for binary file. If the 'b' is not present is a 'plain text' file.

The difference between 'open' and 'open for update' is indicated as:

When a file is opened with update mode ( '+' as the second or third character in the mode argument), both input and output may be performed on the associated stream. However, the application shall ensure that output is not directly followed by input without an intervening call to fflush() or to a file positioning function ( fseek(), fsetpos(), or rewind()), and input is not directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

What is the second parameter/argument to CSV.open( ) in ruby?

From the IO Open Mode documentation:

"r" Read-only, starts at beginning of file (default mode).

"r+" Read-write, starts at beginning of file.

"w" Write-only, truncates existing file
to zero length or creates a new file for writing.

"w+" Read-write, truncates existing file to zero length
or creates a new file for reading and writing.

"a" Write-only, starts at end of file if file exists,
otherwise creates a new file for writing.

"a+" Read-write, starts at end of file if file exists,
otherwise creates a new file for reading and
writing.

File.open, open and IO.foreach in Ruby, what is the difference?

There are important differences beetween those 3 choices.

File.open("file").each_line { |line| puts line }

  • File.open opens a local file and returns a file object
  • the file stays open until you call IO#close on it

open("file").each_line { |line| puts line }

Kernel.open looks at the string to decide what to do with it.

open(".irbrc").class # => File
open("http://google.com/").class # => StringIO
File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/

In the second case the StringIO object returned by Kernel#open actually holds the content of http://google.com/. If Kernel#open returns a File object, it stays open untill you call IO#close on it.

IO.foreach("file") { |line| puts line }

  • IO.foreach opens a file, calls the given block for each line it reads, and closes the file afterwards.
  • You don't have to worry about closing the file.

File.read("file").each { |line| puts line }

You didn't mention this choice, but this is the one I would use in most cases.

  • File.read reads a file completely and returns it as a string.
  • You don't have to worry about closing the file.
  • In comparison to IO.foreach this makes it clear, that you are dealing with a file.
  • The memory complexity for this is O(n). If you know you are dealing with a small file, this is no drawback. But if it can be a big file and you know your memory complexity can be smaller than O(n), don't use this choice.

It fails in this situation:

 s= File.read("/dev/zero") # => never terminates
s.each …

ri

ri is a tool which shows you the ruby documentation. You use it like this on your shell.

ri File.open
ri open
ri IO.foreach
ri File#each_line

With this you can find almost everything I wrote here and much more.

Ruby's File.open and the need for f.close

I saw many times in ruby codes unmatched File.open calls

Can you give an example? I only ever see that in code written by newbies who lack the "common knowledge in most programming languages that the flow for working with files is open-use-close".

Experienced Rubyists either explicitly close their files, or, more idiomatically, use the block form of File.open, which automatically closes the file for you. Its implementation basically looks something like like this:

def File.open(*args, &block)
return open_with_block(*args, &block) if block_given?
open_without_block(*args)
end

def File.open_without_block(*args)
# do whatever ...
end

def File.open_with_block(*args)
yield f = open_without_block(*args)
ensure
f.close
end

Scripts are a special case. Scripts generally run so short, and use so few file descriptors that it simply doesn't make sense to close them, since the operating system will close them anyway when the script exits.

Do we need to explicitly close?

Yes.

If yes then why does the GC autoclose?

Because after it has collected the object, there is no way for you to close the file anymore, and thus you would leak file descriptors.

Note that it's not the garbage collector that closes the files. The garbage collector simply executes any finalizers for an object before it collects it. It just so happens that the File class defines a finalizer which closes the file.

If not then why the option?

Because wasted memory is cheap, but wasted file descriptors aren't. Therefore, it doesn't make sense to tie the lifetime of a file descriptor to the lifetime of some chunk of memory.

You simply cannot predict when the garbage collector will run. You cannot even predict if it will run at all: if you never run out of memory, the garbage collector will never run, therefore the finalizer will never run, therefore the file will never be closed.

Ruby on Rails - run Ruby File.open only when link is clicked

Seems to me like it would be a good fit for server-generated JavaScript responses.

To summarize the concept:

  • create a link which triggers an AJAX request to the server (using link_to with remote: true)
  • let the server decide whether to count the vote or increase the voted-but-not-logged-in-counter and show the modal. Based on this it will generate the corresponding JavaScript which will be executed on the client
  • the client receives a JavaScript response and executes it

It is your decision whether the modal functionality is already loaded from the start and the server just returns showLoginModal(); or whether the server response contains the whole JavaScript to create the modal.

Should I destroy File object after File.read and File.open in Ruby?

It's because File.read method returns string with content of the file, not the File object. And yes, you don't need to use close explicitly if you use File.read method, because ruby does it for you automatically.



Related Topics



Leave a reply



Submit