ZetCode

Ruby write file

last modified October 18, 2026

In this article we show how to write files in Ruby language. We write text and binary files, and use different file modes. This is the counterpart to the Ruby read file article. ZetCode has also a concise Ruby tutorial.

Ruby has File and IO classes to work with files. The examples below create and modify a file named output.txt in the working directory.

File.write whole string and overwrite

The File.write method writes a string to a file. It opens the file, writes the data, and closes the file. If the file exists, its content is overwritten.

write_string.rb
#!/usr/bin/ruby

fname = 'output.txt'

File.write(fname, "Garnet\nTopaz\nOpal\n")
puts File.read(fname)

File.write(fname, "Ruby\n")
puts "After overwrite:"
puts File.read(fname)

The example writes three lines, then overwrites the file with a single line.

$ ./write_string.rb
Garnet
Topaz
Opal
After overwrite:
Ruby

File.open modes and block form

File.open accepts a mode. The "w" mode truncates or creates a file, "a" appends to the end, and "w+" opens the file for reading and writing. When a block is given, the file is automatically closed when the block ends.

open_modes.rb
#!/usr/bin/ruby

fname = 'output.txt'

File.open(fname, 'w') { |f| f.puts 'first line' }
File.open(fname, 'a') { |f| f.puts 'appended line' }

puts "w then a:"
puts File.read(fname)

File.open(fname, 'w+') do |f|
  f.puts 'read-write line'
  f.rewind
  puts "w+ read back:"
  puts f.read
end

The example writes, appends, and then uses w+ to write and read back the content.

$ ./open_modes.rb
w then a:
first line
appended line
w+ read back:
read-write line

Writing with puts, print, << and printf

An open file object supports several output methods. puts adds a newline, print writes as-is, << appends and returns the file object for chaining, and printf or format write formatted text.

write_methods.rb
#!/usr/bin/ruby

fname = 'output.txt'

File.open(fname, 'w') do |f|
  f.puts 'puts line'
  f.print 'print line', "\n"
  f << 'shovel line' << "\n"
  f.printf("%-6s|%5.2f\n", 'pi', 3.14159)
  f.write(format("%03d\n", 7))
end

puts File.read(fname)

The example uses each method to write to the same file.

$ ./write_methods.rb
puts line
print line
shovel line
pi    | 3.14
007

Appending lines to a file

Opening a file in "a" mode keeps the existing content and adds new data at the end.

append_lines.rb
#!/usr/bin/ruby

fname = 'output.txt'

File.write(fname, "Garnet\n")

lines = ['Topaz', 'Opal', 'Ruby']
File.open(fname, 'a') do |f|
  lines.each { |line| f.puts line }
end

puts File.readlines(fname).map(&:chomp).inspect

The example starts with one line and appends three more.

$ ./append_lines.rb
["Garnet", "Topaz", "Opal", "Ruby"]

Writing binary data with wb

Use the "wb" mode to write binary data without any text conversion. The bytes are packed with pack.

binary_write.rb
#!/usr/bin/ruby

fname = 'data.bin'

bytes = [0x52, 0x75, 0x62, 0x79, 0x00, 0xFF, 0x10].pack('C*')

File.open(fname, 'wb') { |f| f.write(bytes) }

puts "size: #{File.size(fname)}"
puts File.binread(fname).unpack('H*')[0]

The example writes seven bytes and reads them back as hexadecimal.

$ ./binary_write.rb
size: 7
5275627900ff10

Checking File.exist? before overwriting

File.exist? tells whether a path already exists. Checking it before writing prevents accidentally overwriting an existing file.

safe_write.rb
#!/usr/bin/ruby

fname = 'output.txt'

if File.exist?(fname)
  puts "#{fname} exists, skipping overwrite"
else
  File.write(fname, "new content\n")
  puts "#{fname} created"
end

puts File.read(fname)

The example creates output.txt only if it does not exist yet.

$ ./safe_write.rb
output.txt exists, skipping overwrite
Garnet
Topaz
Opal
Ruby

Writing with explicit encoding

The mode string may include an encoding, such as "w:UTF-8". Reading can also specify it with the encoding: option. Multibyte characters such as é take more bytes than characters.

encoding_write.rb
#!/usr/bin/ruby

fname = 'output.txt'

text = "Ruby: café, naïve, €10\n"

File.open(fname, 'w:UTF-8') { |f| f.write(text) }

puts "bytesize: #{File.size(fname)}"
puts "encoding: #{File.read(fname, encoding: 'UTF-8').encoding}"
puts File.read(fname, encoding: 'UTF-8')

The example writes text containing non-ASCII characters and reports its byte size and encoding.

$ ./encoding_write.rb
bytesize: 27
encoding: UTF-8
Ruby: café, naïve, €10

In this article we have shown how to write files in Ruby.

List all Ruby tutorials.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.