Ruby Directories

Working with folders and directory structures

📂 What are Directories?

Directories (folders) organize files in your system. Ruby provides powerful methods to create, navigate, list, and manage directories programmatically for efficient file system operations.


# Create a new directory
Dir.mkdir("my_folder") unless Dir.exist?("my_folder")

puts "Directory created successfully!"
                                    

Output:

Directory created successfully!

Key Directory Operations

Create Directory

Make new folders

Dir.mkdir("folder")
FileUtils.mkdir_p("a/b/c")
📋

List Contents

View files and folders

Dir.entries(".")
Dir.glob("*.txt")
🧭

Navigate

Change current directory

Dir.chdir("folder")
Dir.pwd
🗑️

Delete Directory

Remove folders

Dir.rmdir("folder")
FileUtils.rm_rf("folder")

🔹 Creating Directories

Ruby offers multiple ways to create directories. Use Dir.mkdir for single directories or FileUtils.mkdir_p to create nested directory structures in one command, automatically creating parent directories as needed.

require 'fileutils'

# Create single directory
Dir.mkdir("projects") unless Dir.exist?("projects")
puts "Created: projects"

# Create nested directories (creates all parent dirs)
FileUtils.mkdir_p("projects/ruby/examples")
puts "Created: projects/ruby/examples"

# Create multiple directories
["docs", "images", "scripts"].each do |dir|
  Dir.mkdir(dir) unless Dir.exist?(dir)
  puts "Created: #{dir}"
end

# Create with error handling
begin
  Dir.mkdir("test_folder")
  puts "Folder created successfully"
rescue Errno::EEXIST
  puts "Folder already exists"
end

Output:

Created: projects
Created: projects/ruby/examples
Created: docs
Created: images
Created: scripts
Folder created successfully

🔹 Listing Directory Contents

View files and subdirectories within a directory using various methods. Dir.entries shows all entries including hidden files, while Dir.glob allows pattern matching for filtering specific file types or names.

# List all entries (includes . and ..)
entries = Dir.entries(".")
puts "All entries:"
entries.each { |entry| puts "  #{entry}" }

# List without . and ..
files = Dir.entries(".").reject { |f| f == "." || f == ".." }
puts "\nFiles and folders:"
files.each { |f| puts "  #{f}" }

# List only Ruby files
ruby_files = Dir.glob("*.rb")
puts "\nRuby files:"
ruby_files.each { |f| puts "  #{f}" }

# List all text files recursively
all_txt = Dir.glob("**/*.txt")
puts "\nAll .txt files:"
all_txt.each { |f| puts "  #{f}" }

# List directories only
dirs = Dir.entries(".").select { |f| File.directory?(f) && f != "." && f != ".." }
puts "\nDirectories only:"
dirs.each { |d| puts "  #{d}" }

Output:

All entries:
  .
  ..
  main.rb
  test.txt
  docs

Ruby files:
  main.rb
  helper.rb

All .txt files:
  test.txt
  docs/readme.txt

Directories only:
  docs
  images

🔹 Navigating Directories

Change the current working directory and get path information. This is useful when your program needs to work with files in different locations or when building file paths dynamically.

# Get current directory
current = Dir.pwd
puts "Current directory: #{current}"

# Get home directory
home = Dir.home
puts "Home directory: #{home}"

# Change directory temporarily with block
Dir.chdir("projects") do
  puts "Inside projects: #{Dir.pwd}"
  
  # List files here
  puts "Files: #{Dir.entries(".").join(", ")}"
end

# Back to original directory
puts "Back to: #{Dir.pwd}"

# Change directory permanently
Dir.chdir("documents")
puts "Changed to: #{Dir.pwd}"

# Get parent directory
parent = File.expand_path("..")
puts "Parent directory: #{parent}"

Output:

Current directory: /home/user/workspace
Home directory: /home/user
Inside projects: /home/user/workspace/projects
Files: ., .., main.rb, data.txt
Back to: /home/user/workspace
Changed to: /home/user/workspace/documents
Parent directory: /home/user/workspace

🔹 Directory Information

Check directory properties and status before performing operations. These methods help you verify existence, check permissions, and determine if a path points to a directory or file.

dirname = "projects"

# Check if directory exists
if Dir.exist?(dirname)
  puts "Directory exists: #{dirname}"
  
  # Check if it's a directory (not a file)
  puts "Is directory: #{File.directory?(dirname)}"
  
  # Check if empty
  empty = Dir.empty?(dirname)
  puts "Is empty: #{empty}"
  
  # Count entries
  count = Dir.entries(dirname).length - 2  # Exclude . and ..
  puts "Number of items: #{count}"
  
  # Get absolute path
  abs_path = File.absolute_path(dirname)
  puts "Absolute path: #{abs_path}"
else
  puts "Directory does not exist: #{dirname}"
end

# Check multiple paths
paths = ["docs", "images", "videos"]
paths.each do |path|
  status = Dir.exist?(path) ? "exists" : "missing"
  puts "#{path}: #{status}"
end

Output:

Directory exists: projects
Is directory: true
Is empty: false
Number of items: 5
Absolute path: /home/user/workspace/projects
docs: exists
images: exists
videos: missing

🔹 Deleting Directories

Remove directories using different methods depending on whether they're empty or contain files. Dir.rmdir only works on empty directories, while FileUtils.rm_rf can delete directories with all their contents recursively.

require 'fileutils'

# Delete empty directory
begin
  Dir.rmdir("empty_folder")
  puts "Deleted empty folder"
rescue Errno::ENOENT
  puts "Folder doesn't exist"
rescue Errno::ENOTEMPTY
  puts "Folder is not empty"
end

# Delete directory and all contents (use with caution!)
if Dir.exist?("temp_folder")
  FileUtils.rm_rf("temp_folder")
  puts "Deleted temp_folder and all contents"
end

# Safe delete with confirmation
def safe_delete(dirname)
  if Dir.exist?(dirname)
    print "Delete #{dirname} and all contents? (yes/no): "
    response = gets.chomp.downcase
    
    if response == "yes"
      FileUtils.rm_rf(dirname)
      puts "Deleted: #{dirname}"
    else
      puts "Deletion cancelled"
    end
  else
    puts "Directory not found: #{dirname}"
  end
end

safe_delete("old_project")

Output:

Deleted empty folder
Deleted temp_folder and all contents
Delete old_project and all contents? (yes/no): yes
Deleted: old_project

🧠 Test Your Knowledge

Which method creates nested directories automatically?