HOWTO · Ruby

How to Read Lines from a File in Ruby

Learn how to read lines from a file in Ruby using two effective methods: File.readlines and File.foreach. This guide provides clear code examples and detailed explanations to help you master file reading in Ruby, whether you're working with small or large files. Enhance your Ruby skills today!

On this page

Ruby offers two useful ways to read a local text file by line. File.readlines collects the lines into an array, while File.foreach yields each line to a block as it is read. Choose based on whether you need the complete collection or can process each line immediately.

Read All Lines with File.readlines

File.readlines returns an array of strings, one for each line. Use it when you need to inspect the whole collection, revisit lines, or access a line by its array index. Each string normally retains its line ending, so call chomp when displaying or processing the text without that ending.

Run this example:

require "tempfile"

Tempfile.create("ruby-lines") do |file|
  file.write("First item\nSecond item\nThird item\n")
  file.flush

  lines = File.readlines(file.path)
  lines.each do |line|
    puts line.chomp
  end
end

The temporary file makes the example self-contained. In your program, replace its path with the path of your local file. The returned array keeps all line strings in memory, so memory use grows with the file size. For a modest file or when you need indexed access, that tradeoff is often convenient. For a very large file that you only need to scan once, process lines incrementally instead.

Read One Line at a Time with File.foreach

File.foreach opens a file and yields each line to the supplied block. It does not build and return an array of all lines; after each block iteration, the program can move on to the next line. This pattern is useful for filtering, counting, or transforming a large file when you do not need to keep every line.

Run this example:

require "tempfile"

Tempfile.create("ruby-lines") do |file|
  file.write("First item\nSecond item\nThird item\n")
  file.flush

  File.foreach(file.path) do |line|
    puts line.chomp
  end
end

The block receives each line including its terminator when one is present. chomp removes the trailing newline (and a carriage-return/newline pair where applicable) without removing other characters from the end of the line. If you need the original line ending, process line directly instead. File.foreach manages opening and closing the file around block iteration, including when the block exits early.

Choose a Method and Handle Common Cases

Use File.readlines when an array is part of the task: for example, if you need to access lines[1] or make multiple passes over the collected lines. Use File.foreach when a single pass is enough and you want to avoid retaining the complete file in memory. Neither method is universally better; the file size and the processing you need determine the useful choice.

Both methods can fail if the path does not exist or the process lacks permission to read it. Handle expected filesystem errors at the point where you can give a useful response. For example, a rescue for a missing path can report that the input file was not found; permission failures can be handled separately as Errno::EACCES. Avoid rescuing every exception indiscriminately, since that can hide programming errors.

When you only need selected lines by position, File.readlines makes array indexing straightforward, though it still reads the whole file. When you need to find lines matching a condition, File.foreach can stop early with break, so it need not scan the rest after the answer is found. Both examples here read local files; fetching a URL requires a different API and is outside this guide’s scope.