Ruby File Operations

Reading, writing, and managing files in Ruby

📁 What are File Operations?

File operations in Ruby allow you to read, write, and manipulate files on your system. Ruby provides simple, powerful methods for file handling, making it easy to store data, read configurations, and process text files.


# Simple file write and read
File.write("hello.txt", "Hello, Ruby!")
content = File.read("hello.txt")
puts content
                                    

Output:

Hello, Ruby!

File Operation Types

📖

Reading Files

Load content from files

File.read("file.txt")
File.readlines("file.txt")
✍️

Writing Files

Save data to files

File.write("file.txt", data)
File.open("file.txt", "w")
🔍

File Checks

Verify file properties

File.exist?("file.txt")
File.directory?("folder")
🗂️

File Management

Organize and modify files

File.rename(old, new)
File.delete("file.txt")

🔹 Reading Files

Ruby provides multiple ways to read file content. You can read entire files at once, read line by line, or read specific amounts of data. Choose the method based on your file size and processing needs.

# Read entire file as string
content = File.read("example.txt")
puts "File content: #{content}"

# Read file as array of lines
lines = File.readlines("example.txt")
puts "Number of lines: #{lines.length}"
lines.each_with_index do |line, index|
  puts "Line #{index + 1}: #{line}"
end

# Read file line by line (memory efficient)
File.foreach("example.txt") do |line|
  puts "Processing: #{line.strip}"
end

# Read with block (auto-closes file)
File.open("example.txt", "r") do |file|
  while line = file.gets
    puts line
  end
end

Output:

File content: First line
Second line
Third line
Number of lines: 3
Line 1: First line
Line 2: Second line
Line 3: Third line
Processing: First line
Processing: Second line
Processing: Third line

🔹 Writing Files

Writing files in Ruby is straightforward. You can overwrite existing files, append to them, or create new files. Ruby automatically handles file creation and closing when using the simple write methods.

# Simple write (overwrites file)
File.write("output.txt", "Hello, World!")
puts "File written successfully"

# Write multiple lines
data = "Line 1\nLine 2\nLine 3"
File.write("multiline.txt", data)

# Append to file
File.write("output.txt", "\nNew line", mode: "a")

# Write with block (auto-closes)
File.open("data.txt", "w") do |file|
  file.puts "First line"
  file.puts "Second line"
  file.write "Third line without newline"
end

# Write array to file
items = ["Apple", "Banana", "Cherry"]
File.open("fruits.txt", "w") do |file|
  items.each { |item| file.puts item }
end

puts File.read("fruits.txt")

Output:

File written successfully
Apple
Banana
Cherry

🔹 File Modes

File modes determine how Ruby opens and interacts with files. Understanding modes is crucial for preventing data loss and ensuring your file operations work correctly. Each mode has specific permissions and behaviors.

# "r" - Read only (file must exist)
File.open("read.txt", "r") do |file|
  puts file.read
end

# "w" - Write only (creates or overwrites)
File.open("write.txt", "w") do |file|
  file.puts "This overwrites everything"
end

# "a" - Append (adds to end of file)
File.open("append.txt", "a") do |file|
  file.puts "This is added to the end"
end

# "r+" - Read and write (file must exist)
File.open("readwrite.txt", "r+") do |file|
  content = file.read
  file.rewind
  file.puts "Modified: #{content}"
end

# "w+" - Read and write (creates or overwrites)
File.open("newfile.txt", "w+") do |file|
  file.puts "New content"
  file.rewind
  puts file.read
end

Output:

New content

🔹 File Checks and Information

Before working with files, it's important to check if they exist and get their properties. Ruby provides many methods to inspect files, helping you avoid errors and make informed decisions about file operations.

# Check if file exists
if File.exist?("test.txt")
  puts "File exists"
else
  puts "File not found"
end

# Check if it's a file or directory
puts File.file?("test.txt")
puts File.directory?("test.txt")

# Get file size
if File.exist?("test.txt")
  size = File.size("test.txt")
  puts "File size: #{size} bytes"
end

# Check if file is empty
puts File.zero?("test.txt")

# Get file permissions
puts File.readable?("test.txt")
puts File.writable?("test.txt")
puts File.executable?("test.txt")

# Get file timestamps
if File.exist?("test.txt")
  puts "Created: #{File.ctime('test.txt')}"
  puts "Modified: #{File.mtime('test.txt')}"
  puts "Accessed: #{File.atime('test.txt')}"
end

Output:

File exists
true
false
File size: 42 bytes
false
true
true
false
Created: 2024-01-15 10:30:00
Modified: 2024-01-15 10:35:00
Accessed: 2024-01-15 10:40:00

🔹 File Management Operations

Ruby allows you to rename, copy, move, and delete files programmatically. These operations help you organize files, clean up temporary data, and manage your file system efficiently from within your Ruby programs.

# Create a test file
File.write("original.txt", "Original content")

# Rename file
File.rename("original.txt", "renamed.txt")
puts "File renamed"

# Copy file (using FileUtils)
require 'fileutils'
FileUtils.cp("renamed.txt", "copy.txt")
puts "File copied"

# Move file
FileUtils.mv("copy.txt", "moved.txt")
puts "File moved"

# Delete file
File.delete("moved.txt") if File.exist?("moved.txt")
puts "File deleted"

# Create directory
Dir.mkdir("new_folder") unless Dir.exist?("new_folder")
puts "Directory created"

# List files in directory
files = Dir.entries(".")
puts "Files: #{files.first(5).join(', ')}"

# Delete directory
Dir.rmdir("new_folder") if Dir.exist?("new_folder")
puts "Directory deleted"

Output:

File renamed
File copied
File moved
File deleted
Directory created
Files: ., .., file1.txt, file2.txt, folder
Directory deleted

🔹 Safe File Operations

Always handle file operations safely to prevent data loss and crashes. Use exception handling to catch errors, ensure files are properly closed, and validate file paths before operations. This makes your code more reliable.

# Safe file reading with exception handling
begin
  content = File.read("important.txt")
  puts content
rescue Errno::ENOENT
  puts "Error: File not found"
rescue Errno::EACCES
  puts "Error: Permission denied"
rescue => e
  puts "Error: #{e.message}"
end

# Ensure file is closed
file = File.open("data.txt", "w")
begin
  file.puts "Important data"
ensure
  file.close
  puts "File closed safely"
end

# Better: Use block (auto-closes)
File.open("data.txt", "w") do |file|
  file.puts "Data is safe"
end

# Check before operations
filename = "config.txt"
if File.exist?(filename) && File.readable?(filename)
  content = File.read(filename)
  puts "Config loaded: #{content}"
else
  puts "Cannot read config file"
end

Output:

Error: File not found
File closed safely
Config loaded: setting=value

🧠 Test Your Knowledge

Which method reads an entire file as a string?