Files & Directories in Ruby: A Primer
Because sometimes the documentation has too much information.
Two important classes: File & Dir.
Dir works with directories. File works with files.
Dir
It’s a lot like working in the command line!
Getting Started
Dir.pwd
: returns the path to the current working directory as a string.
Dir.chdir("../folder_name”)
: changes current directory to the directory in the argument.
Dir.glob("pattern")
: looks at the current directory and returns an array of files that match that pattern.
- Example 1: a pattern could be
"*txt"
andDir.glob
would return all of the files that end in .txt within the current directory. - Example 2: a double asterisk like
"**/*.txt"
will tellDir.glob
to look for any files that end in .txt within any directory above the current directory. - Example 3: to include multiple types of files, use curly braces like this
"*.{rb,txt}"
Creating a Dir Object
Dir.new("directory_name")
: creates a new directory object that references the directory that’s been passed in as an argument. So if you have a directory named “data”, with three files in it, this method creates a Dir object with those three files accessible as part of the object.
Pssst…if this doesn’t make sense yet… keep reading through the “Using a Dir Object” section and then come back (context can be helpful)
Dir.open("directory_name") {block}
: similar to Dir.new
but allows you to use a block to work with the directory.
Using a Dir Object
Directory objects are often used by storing the directory in a variable:
my_directory = Dir.new("data")
Then, you can do things like iterate over my_directory
:
my_directory.each { |file| puts file }
Or use instance methods like #entries
:
my_directory.entries
Which returns the contents of the directory as an array.
File
Path Methods
File.absolute_path("file.txt")
: returns a string of the absolute path of a file (the file.txt file in particular). An absolute path is the path from the root directory. A relative path is the path from the current working directory.
*Interesting note — not all operating systems use the same style in their path structures (for example — Mac uses forward slashes, and Windows uses back slashes).
File.join("path", "file.txt")
: returns a string of the joined arguments in the format that is applicable to the current operating system. *Solves the problem from the interesting note above! Can take as many arguments as you want.
- Example 1: if my current directory is
"/Users/Mindy/Desktop"
,File.join(Dir.pwd, "file.txt")
would return"/Users/Mindy/Desktop/file.txt"
on a Mac or"\Users\Mindy\Desktop\file.txt"
on a PC. - Example 2:
File.join("Users", "John", "Downloads", "file.txt")
would return"/Users/John/Downloads/file.txt"
on a Mac or"\Users\John\Downloads\file.txt"
on a PC.
File.basename("path")
: returns the name of the file that the path leads to as a string. A second optional argument can remove part of the string.
- Example 1:
File.basename("/Users/Mindy/Desktop/file.txt", ".txt")
returns"file"
- Example 2:
File.basename("/Users/Mindy/Desktop/file.txt", "xt")
returns"file.t"
Reading & Writing Files
File.new("code.rb", "r")
: creates a new File object. The file itself can, but doesn’t have to exist as this will create it if it doesn’t exist. The second parameter can be any of the following.
r
— for read, allows you to output the contents of a file by calling read on that file, but only once. It’s like a VHS tape and you have to rewind it to read it again.
file = File.new("hello.txt", "r")file.read # returns file contents
file.read # returns nothing
file.rewind # like a VHS tape
file.read # returns file contents
w
— for write, writes over everything in the existing file (if there is one).w+
— for read and write, writes over everything in the existing file (if there is one) and also adds the read permission.a
— for append, adds any new content at the end of the existing file (if there is one).
File.open("code.rb", "w")
: a synonym for File.new
unless it also includes a block. The File object will automatically be closed when the block terminates.
Instance Methods
This is after we create a File object, let’s call it file
.
file.readline
: returns the file’s contents one line at a time. Returns an error when it gets to the end.
file.gets
: same as #readline
except instead of getting an error, the function returns nil
.
file.readlines
: returns the file’s contents as an array of single lines.
file.each {block}
: calls a block on each individual line.
file.puts("text")
: writes the argument to the file, returns nil
, and adds a new line.
file.write("text")
: writes the argument to the file, returns the number of characters in the argument, and does not add a new line.
Other Methods
File.directory?("name")
: returns true if the argument is a directory. Why would this be useful? When iterating through a directory or using the#entries
method from above, the current directory (.
) and the parent directory (..
) are included in that list. We may want to include only files that are or are not directories.
my_directory.each do |file|
puts file unless File.directory?(file)
end
The above will only print the file if it is not a directory.
Note: Information was gleaned from various tutorials. Some methods or use cases may be out of date at the time of publishing. Please be gracious!
That’s all, for now!
File.close