
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
vsURI.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
):
Mode | Meaning |
---|---|
"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
, andStringIO
for advanced tasks.
Docs: File (Ruby 3.x), File::Stat, FileTest