Skip to content
Reading and Writing Files
step 1/7

Reading — step 1 of 7

Learn

~2 min readFile I/O

Reading and writing files is a daily task. Ruby's File and IO classes give several layers of convenience — pick the right one for the job.

Reading whole files

# Read everything into a string:
contents = File.read('config.yml')

# Read into an array of lines (with newlines kept):
lines = File.readlines('data.txt')

# Read into an array of lines with chomp:
lines = File.readlines('data.txt', chomp: true)

For small-to-medium files. Don't use File.read on huge files — you'll OOM.

Reading line by line (memory-efficient)

File.foreach('huge.log') do |line|
  process(line)
end

foreach streams — only one line in memory at a time. Use this for files larger than RAM, log files, etc.

Writing files

File.write('out.txt', 'hello world')                # overwrite
File.write('out.txt', 'append', mode: 'a')          # append

File.write opens, writes, and closes for you. One-shot convenience.

Block form — auto-close

For any case where you need to do multiple operations on the same file:

File.open('data.txt', 'r') do |f|
  while line = f.gets
    puts line
  end
end
# file is automatically closed here, even if the block raises

The block form is the IDIOMATIC pattern. The file is auto-closed when the block exits — like Python's with open().

File modes

  • 'r' — read (default)
  • 'w' — write, TRUNCATES the existing file
  • 'a' — append
  • 'r+' — read+write
  • 'w+' — write+read, truncates
  • Add b for binary: 'rb'

Common helpers

File.exist?('foo.txt')
File.size('foo.txt')
File.basename('/a/b/c.txt')      # => 'c.txt'
File.dirname('/a/b/c.txt')        # => '/a/b'
File.extname('foo.tar.gz')        # => '.gz'
File.join('a', 'b', 'c.txt')      # cross-platform path join
Dir.glob('*.rb')                  # ruby files in cwd
Dir.glob('**/*.rb')                # recursive

STDIN, STDOUT, STDERR

These are pre-opened IO objects:

STDIN.gets                  # read a line (also: gets in scripts)
STDOUT.puts 'normal output'  # also: puts
STDERR.puts 'error msg'      # also: warn 'msg'

Useful for shell-style scripts where you read one stream and write another.

Common mistakes

  • Forgetting to close files — use the block form. Manual File.open without close leaks file descriptors.
  • Reading huge files with File.read — OOMs on multi-GB files. Use foreach for streaming.
  • Mode mistakes'w' TRUNCATES the file. To read AND write without losing existing content, use 'r+'.
  • Encoding issues — by default Ruby uses your system's default encoding. Force with File.read(path, encoding: 'UTF-8').
  • Forgetting File.join — hardcoded / paths break on Windows. Use File.join for cross-platform code.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…