1. Technology
You can opt-out at any time. Please refer to our privacy policy for contact information.

Reading Files

By

Reading Files

Ruby programs rarely exist in their own world, they need some way to communicate with the outside world, store data or load data, and one of the primary ways of doing this is to load or store data from a file. Ruby provides a clean and Ruby-like interface for dealing with files.

Reading Simple Files

Ruby file access is provided via the File class. There are class methods to open, create and read files, and instance methods to deal with individual open files. To open an existing file, there are two ways.

The first is with File.new, which creates a new file object (but not necessarily a new file on the filesystem). This is just like any other SomeClass.new method, it returns a new instance of the class, in this case representing an open file. It takes one argument at the minimum, the name of the file to open. So, to open the file data.txt I could say f = File.new("data.txt"). This file is, by default, opened in read only mode, and will raise an exception if the file cannot be opened either because it does not exist, or because you don't have permissions to read it.

Using what you know now, you can write simple programs that read from files such as this one.


f = File.open("name.txt")
name = f.gets.chomp  # Look familiar?
puts "Your name is #{name}"
f.close

Seems simple, no? Open a file, read the name, print the name, close the file. Anything look familiar with the second line? The gets.chomp idiom is used here as well, but they're not just similar methods as you use to read from the keyboard, they're the same methods. The STDIN object and a File object are both IO objects, and they share many of the same methods. OK, that was easy, but what if you forget to close the file? The file will be closed when the file object is garbage collected, but there are plenty of ways an errant or unneeded reference to the file object can stick around and it'll never get garbage collected, so it'll never be closed. Instead of using File.new, a better way is to use File.open.

The File.open method takes the same parameters as the File.new method (including a few optional ones not discussed above), but it also takes a block parameter. If you were to pass a block to File.open, it'll pass the file parameter to the block and after the block has done its thing will close the file automatically. This prevents the File object from hanging around in memory (even if you manage your references carefully, the garbage collector can be unpredictable) and the file not being closed. The File.open method itself returns whatever the block returns. So, we could re-write out little example much more succinctly (and safely).


name = File.open('name.txt') {|f| f.gets.chomp }
puts "Your name is #{name}"

Methods for Reading

There are a few methods you may want to use to read strings from files. Note that these are for reading strings, as in text files. Some may be used to read binary data, but all of these are really designed for reading text.

The gets method, as seen above, will read an entire line and return it as a string. As most text data is newline delimited, this is possible the most useful method for reading. However, if what you really want to do is iterate over the lines in a file, the each method is probably what you're looking for. Just like iterating over an array, this will iterate over the lines in a file, almost as if it were an array of strings.


# Prints the names stored in a file
puts "The following names are in the file:"
File.open("names.txt") do|f|
  f.each {|n| puts n }
end

There are also some lower level methods you may be interested in. The File#read method reads a set number of bytes into a buffer. This is done internally by things like gets, but it can be used yourself. It takes a single required parameter, the number of bytes you'd like to read. This can be useful for text files that have set column widths, or other such rigid structures (which are not very common in modern files, but common in much older files).


puts "The first 4 bytes of the file are: "
puts File.open("names.txt").read(4)

But even these types of operations are not commonplace in Ruby. You usually just use the shortcuts.

Shortcuts

Want to read the contents of a file into a string? The whole thing, not just a single line or a chunk of it into a buffer. OK, there's a class method for that. Calling string = File.read('data.txt') will do just that.

How about all of the file's lines in an array of strings? You just need to do lines = File.readlines('data.txt'). It couldn't be any easier to quickly get data into Ruby doing this.

  1. About.com
  2. Technology
  3. Ruby
  4. Beginning Ruby
  5. Files and Directories
  6. Reading Files

©2014 About.com. All rights reserved.