Skip to Content
Course content

66: FileUtils for File Operations

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I see this all the time when I'm reviewing code from developers moving into Ruby: they treat the File class as the one-stop shop for every single interaction with the disk. They assume that because it's called File, it must handle every "file-related" task you could possibly imagine.

The "File Class Does Everything" Myth

Here is the reality: the File class is great for reading, writing, and checking the properties of a single file. But the moment you try to do "system-level" operations—like moving a directory or deleting a folder that isn't empty—File will let you down. Look at this example:

# Let's say we have a folder called 'old_logs' with 50 files inside it.
File.delete('old_logs') 
# Result: Errno::EISDIR (Is a directory)

Ruby is telling you, "Hey, this is a directory, not a file!" To get around this using only the File class, you'd have to write a recursive loop to find every file, delete them individually, and then finally delete the directory. That's a waste of your time. I don't want you writing boilerplate when the standard library already solved this for us.

Moving to FileUtils for Shell-Like Power

This is where FileUtils comes in. Think of FileUtils not as a way to handle file content, but as a way to perform shell commands (like cp, mv, and rm -rf) directly within your Ruby code. You'll need to require 'fileutils' because, unlike the File class, it isn't loaded by default.

One of the most useful methods you'll use is mkdir_p. The 'p' stands for parents. If you try to create /backups/2023/october but none of those folders exist yet, a standard Dir.mkdir will crash. FileUtils.mkdir_p just makes it happen, creating every missing folder in the chain.

require 'fileutils'

# No matter how deep the path is, this just works.
FileUtils.mkdir_p('archives/logs/daily')

Handling Bulk Moves and Recursive Copies

When you're managing a project's assets or logs, you rarely move one file. You usually move groups. FileUtils.mv is your friend here. It handles both files and directories seamlessly. If you need to copy an entire directory structure—say, duplicating a template folder for a new user—use cp_r (the 'r' is for recursive).

# Copying a configuration template directory to a user's specific folder
FileUtils.cp_r('config/templates/default', 'config/users/user_42')

# Moving a finished export to the archives
FileUtils.mv('exports/report_final.csv', 'archives/2023/report_final.csv')

The Nuclear Option: rm_rf

Between us, FileUtils.rm_rf is the most dangerous method in this module. It's the Ruby equivalent of rm -rf /. It deletes a file or a directory (and everything inside it) without asking for permission and without raising an error if the path doesn't even exist.

I use it frequently for cleaning up temporary build directories, but please, be incredibly careful with the variables you pass into it. One misplaced string and you could wipe out your entire project directory.

# Cleaning up a temporary directory before a new build
FileUtils.rm_rf('tmp/cache') 



📋 Practical Task

Exercise: Automated Log Rotation and Archiving Script

You need to build a script that cleans up a messy logs/ directory. Your script should perform the following sequence of operations:

  • Create a directory path archives/logs/backup_current using mkdir_p to ensure the full path exists.
  • Assume there are several files in the logs/ folder (you can create a few dummy files like log1.txt, log2.txt).
  • Move all files ending in .txt from the logs/ folder into the archives/logs/backup_current folder.
  • Finally, delete the original logs/ directory and all its remaining contents using the "nuclear" method.

Requirement: Your solution must use FileUtils for the directory creation, the moving, and the final deletion.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.