Ruby File and Directory Cheatsheet

Ryan Novas
4 min readAug 25, 2015

--

Now that I’ve started making Ruby apps that are a little more advanced, files and directories need to be created dynamically on the fly. This means it is no longer enough to flip into terminal (or heavens forbid, a GUI) for my file manipulation needs.

Instead, I need to programmatically generate files and folders right in the app. Fortunately, Ruby has built-in File and Dir classes, as well as the powerful FileUtils models.

Creating Files in Ruby:

Manually Create a Single File

File.open "your_file.txt", "w"

That one was easy. Just keep in mind that you need to set permissions. In the last case, we created the file with “write” permissions.

Dynamically Create Multiple Files

Creating a single file like that is simple, but hardly any better than doing it in terminal. What if you want to make a whole list of files, and you don’t know what their specific names will be? For example, you may want to set up a text file with information about everyone who uses your application. In that case, you can just iterate through the list of files.

names_array = [‘Ryan’, ‘Tom’, ‘Sam’]
names_array.each {|name| File.open “#{name.downcase}.txt”, “w”}

This will iterate through the names array and create a text file for each name within it.

Writing to Files in Ruby

Manually Write to a Single File

Now that you know how to make files, it is time to put something in them.

file = File.open “your_file”, “w”
file.write(‘whatever’)
file.close

Of course, this still isn’t very useful. What if we want to make and write a number of files at one time.

Write to Multiple Files

Let’s keep working with the names, except as a hash. You would just iterate through each of the key-value pairs, opening a file, and then writing the relevant data to it. Your code would look something like this:

names_hash = {ryan: {location: ‘Brooklyn’, age: ‘26’},
tom: {location: ‘Queens’, age: ‘27’},
sam: {location: ‘Bronx’, age: ‘25’}}

names_hash.each do |person, attributes|
File.open “#{person}.txt”, ‘w’ do |file|
file.write “#{attributes[:location]} \n #{attributes[:age]}”
file.close
end
end

And it would output three files, named Ryan, Tom, and Sam, with their location and age.

Appending Text to Files in Ruby

What if we get some more information about everyone in the name hash’s education and need to update their text files?

names_hash = 
{ryan:{location: ‘Brooklyn’, age: ‘26’, education: 'Bates'},
tom:{location: ‘Queens’, age: ‘27’, education: ‘Bowdoin’},
sam:{location: ‘Bronx’, age: ‘25’, education: ‘Colby’}}
names_hash.each do |person, attributes|
File.open “#{person}.txt”, ‘w’ do |file|
file.write “#{attributes[:education]}”
file.close
end
end

If you just tried that out, you’ll see that each of the files has been over-written by just the person’s education. This is because the ‘w’ flag only allows for creating and overwriting.

What we would use is the ‘a’ tag, which stands for append. The correct line of code would be:

File.open “#{person}.txt”, ‘a’ do |file| 
file.write “#{attributes[:education]}”
file.close
end

Deleting Files in Ruby

If we decide that we only want users who are under 27 on our site, we may want to clean up all the files that we’ve made for anyone older than that. Obviously we are too lazy to look through each of them. Instead we would do:

names_hash.each do |person, attribute|
old= “#{person}.txt”
File.delete(old) unless attribute[:age] < 27
end

Creating Directories in Ruby

Create a Non-nested Directory in Ruby

If you’re using enough files to have made it this far, you probably either have a mess or have been manually creating directories in terminal or through a GUI. Here’s how to do it in Ruby with the Dir class.

Dir.mkdir “your_directory”

However, if you try running the rb file twice, you may get an error like this:

test1.rb:3:in `mkdir’: File exists @ dir_s_mkdir — your_directory (Errno::EEXIST)

You cannot make two directories with the same name in the same folder. We can avoid this error by using the “.exist?” method from the File class, which will check to make sure the current directory is not already populated with a sub-directory of the same name.

Dir.mkdir “your_directory” unless File.exist? "your_directory"

Create a Nested Directory in Ruby

Adding directories to your root folder probably won’t be enough for many of the programs you’ll build. If you want to make a nested directory, you’ll need to use a FileUtils model.

require ‘FileUtils’
FileUtils.mkdir_p ‘./parent_folder/another_folder/folder’

FileUtils is much more powerful than the File or Dir class alone. It has a ton of similar functionality, but it can also move, copy, rename files, change links, and much more. However, these are more advanced functions that will probably be covered in a separate blog post.

Deleting Directories in Ruby

Remove a Directory

If your directory is empty, deleting it as simple as running:

Dir.delete “your_file”

However, if your directory has anything in it, this will raise an error. To delete a populated directory, you need to use FileUtils. However, this opens you up to a number of security risks, and while I was experimenting with the various methods, there was some unintended behavior. Since I accidentally trashed an entire folder unintentionally, and still can’t figure out how I did it, I’m going to leave this technique for a later blog post.

--

--