Skip to content
Go back

Working with Files in Ruby

Updated:
Working with Files in Ruby

Note (2025): Ruby’s file handling APIs haven’t changed much over the years. This post is still a solid introduction to Ruby file I/O. Only a few details (like Kernel#open vs URI.open) have shifted. Documentation links have been updated to Ruby 3.x.


Table of Contents

Open Table of Contents

Files and the IO class

All input/output in Ruby is built on the IO class. File inherits from IO, adding filesystem-specific methods. For example:

File.exist?("foo.txt")
# => true or false

Opening a File

File.open("file.txt") do |file|
  # do something
end

Modes (2nd argument to open or new):

ModeMeaning
"r"Read-only (default)
"r+"Read/write, starting at beginning
"w"Write-only, truncates or creates file
"w+"Read/write, truncates or creates file
"a"Append, creates file if missing
"a+"Read/write + append
"b"Binary mode
"t"Text mode

Reading from a File

file = File.new("README.md")
file.read           # whole file
file.gets           # one line
file.readlines      # array of lines

Shortcuts:

File.read("README.md")      # returns contents as string
File.foreach("README.md") { |line| puts line }

⚠️ For large files, prefer streaming (using gets, each_line, foreach) instead of read.

Treating Files as Streams

File.open("bigfile.txt") do |f|
  f.each_line do |line|
    process(line)
  end
end

Seeking within a File

You can jump around with pos or seek:

file.pos = 10
file.seek(20, IO::SEEK_SET)
file.seek(-5, IO::SEEK_END)

Writing to Files

f = File.new("data.out", "w")
f.puts "Hello Ruby"
f.close

Append instead:

File.open("data.out", "a") { |f| f.puts "Appended line" }

Querying File Objects

Ruby offers FileTest and File::Stat helpers:

File.file?("README.md")       # true
File.directory?("src")        # true
File.size("README.md")        # => bytes
File.executable?("script.sh") # true/false

Wrap-up

Docs: File (Ruby 3.x), File::Stat, FileTest


You might also like


Share this post on:

Previous Post
Retrieving a Random Row in ActiveRecord
Next Post
WeakMaps in JavaScript