Working with Files in Ruby

Working with Files in Ruby


ruby file-io
Last updated on

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.


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
  • With a block: file closes automatically.
  • Without a block: you must call close manually.

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
  • getc → read one character.
  • getbyte → read one byte.
  • ungetc → push a character back.

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

  • Use File.open with a block to avoid leaks.
  • For large files, prefer streaming methods.
  • Explore FileUtils, Pathname, and StringIO for advanced tasks.

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


You might also like

© 2025 Syed Aslam