RubyGuides
Share this post!

Working With Files and Folders in Ruby

In this article you’ll learn how to:

  • Read & write files with Ruby
  • List the contents of directories
  • Create temporary files
  • Create new folders
  • Get information about files (size, type, directory name…)

ruby working with files

Let’s get started!

How to Read Files In Ruby

To read a file in Ruby you have to open it first!

The File class allows you to open a file:

file = File.open("users.txt")

This will return a File object to you, not the contents of the file.

You can use methods (Ruby commands) to work with this object & get the contents of the file.

Note: It’s useful to know that the following methods come from the IO class, which is the parent class of File.

These methods include:

  • gets (read one line)
  • read (whole file, or a set amount of bytes)
  • rewind (go back to start of file)
  • close (free memory & resources)

Using gets you can read one line at a time, and using read you can read the whole file or a specified number of bytes.

Examples:

# Read the first line
file.gets
# => "user1\n"

# Go back to the start of the file
file.rewind  

# Read the whole file
file.read
# => "user1\nuser2\nuser3\n"

# We are done, close the file.
file.close

You will need to remember to call close on your file, so the contents are flushed to disk (if you wrote to it) & the file descriptor is made available.

If you want to read the whole file with just one line of code you can use File.read, in this case you don’t need to close the file.

Example:

data = File.read("users.txt")
# => "user1\nuser2\nuser3\n"

You can then split the data into an array of lines with the split method.

If you want to process the file one line at a time, you can use the foreach method:

File.foreach("users.txt") { |line| puts line }

This is useful for big files where you don’t want to read the whole file into memory.

How to Write to a File in Ruby

When opening a file for writing, you need to add the “w” flag as the second argument.

File.open("log.txt", "w") { |f| f.write "#{Time.now} - User logged in\n" }

This will rewrite the previous file contents.

If you want to add new content to the file, use the “a” (append) flag.

Another way to write data into a file is to use File.write:

File.write("log.txt", "data...")

There is no difference other than the 2nd version (File.write) being a lot shorter than the 1st one (File.open with a block).

File Operations

You can do other things with files, besides reading & writing to them…

For example, you may want to know if a file exists or to get a list of files for the current directory.

You are going to be using methods like:

  • rename
  • size
  • exists?
  • extname
  • basename
  • dirname
  • directory?
  • file?

Let’s see a few examples:

# Renaming a file
File.rename("old-name.txt", "new-name.txt")

# File size in bytes
File.size("users.txt")

# Does this file already exist?
File.exists?("log.txt")

# Get the file extension, this works even if the file doesn't exists
File.extname("users.txt")
# => ".txt"

# Get the file name without the directory part
File.basename("/tmp/ebook.pdf")
# => "ebook.pdf"

# Get the path for this file, without the file name
File.dirname("/tmp/ebook.pdf")
# => "/tmp"

# Is this actually a file or a directory?
File.directory?("cats")

The last example makes more sense if you are looping through the contents of a directory listing.

def find_files_in_current_directory
  entries = Dir.entries(".")

  entries.reject { |entry| File.directory?(entry) }
end

You can also get stats for a file, like file size, permissions, creation date, etc:

File.stat("/tmp")

How to Create a Temporary File

If you want a file that gets deleted automatically you can create a temporary file.

Here’s how:

require 'tempfile'

Tempfile.create { |f| f << "abc\n" }

This is built into Ruby so you don't have to install any gems.

Directory Operations

Using Dir.glob you can get a list of all the files that match a certain pattern.

Here are some examples:

# All files in current directory
Dir.glob("*")

# All files containing "spec" in the name
Dir.glob("*spec*")

# All ruby files
Dir.glob("*.rb")

This one line of code will recursively list all files in Ruby, starting from the current directory:

Dir.glob("**/**")

Use this if you only want to search for directories:

Dir.glob("**/**/")

Using the Dir class it's also possible to print the current working directory:

Dir.pwd

Check if a directory is empty:

Dir.empty?("/tmp")
# false

Check if a directory exists:

Dir.exists?("/home/jesus")
# true

Create a new directory:

Dir.mkdir("/tmp/testing")

Create a temporary directory with mktmpdir:

Dir.mktmpdir do |dir|
  File.write(dir + "/log.txt", "test")
end

How to Use The FileUtils Module

There are some extra file handling utilities you can get access to within the FileUtils module.

For example, you can compare files, touch a file (to update the last access & modification time), or copy files & directories with cp_r.

Like this:

require 'fileutils'

FileUtils.compare_file("a.txt", "b.txt")
FileUtils.touch("/tmp/lock")
FileUtils.cp_r("data", "backup")

Btw the "r" in cp_r stands for "recursive".

Summary

You have learned how to manage files & folders in Ruby using built-in methods like File.read & File.write.

Thanks for reading!