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
withremote: 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
How to "Pretty" Format Json Output in Ruby on Rails
In Ruby on Rails, How to Format a Date With the "Th" Suffix, as In, "Sun Oct 5Th"
How Does Instance_Eval Work and Why Does Dhh Hate It
What's the Best Way to Model Recurring Events in a Calendar Application
Cannot Load Such File - Script/Rails: Getting This Error While Remote Debugging Through Rubymine
Cannot Install Json Gem in Rails Using Windows
Best Practices With Stdin in Ruby
Executing Code For Every Method Call in a Ruby Module
What Does a Double * (Splat) Operator Do
What Are the Brackets [5.1] After Activerecord Migration and How Does It Work
How Does the Magic Comment ( # Encoding: Utf-8 ) in Ruby Work