Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

file-io

ruby

All of the following API do the same thing: open a file and call a block for each line. Is there any preference we should use one than another?

File.open("file").each_line {|line| puts line} open("file").each_line {|line| puts line}    IO.foreach("file") {|line | puts line} 
like image 373
pierrotlefou Avatar asked Nov 13 '09 05:11

pierrotlefou


People also ask

When manipulating a file What is the difference between foreach and Readlines methods in Ruby?

Explanation: The difference between the method foreach and the method readlines is that the method foreach is associated with a block. However, unlike the method readlines, the method foreach does not return an array. 9.

What are the ruby file open modes?

Ruby allows the following open modes: "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.

How file IO is performed in Ruby explain the important statements used in file IO operations?

Ruby provides a whole set of I/O-related methods implemented in the Kernel module. All the I/O methods are derived from the class IO. The class IO provides all the basic methods, such as read, write, gets, puts, readline, getc, and printf.

When opening a file What does the mode a mean in Ruby?

Ruby students also learnAppend/Write only permission is denoted by 'a'. The main difference from the previous option is that the file pointer starts at the end of the file. This means the existing data in the file is not overwritten.


1 Answers

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.

like image 78
johannes Avatar answered Oct 02 '22 17:10

johannes