Problem
Given a filename, you want to see whether the corresponding file exists and is the right kind for your purposes.
Solution
Most of the time you'll use the File.file? predicate, which returns true only if the file is an existing regular file (that is, not a directory, a socket, or some other special file).
filename = 'a_file.txt' File.file? filename # => false require 'fileutils' FileUtils.touch(filename) File.file? filename # => true
Use the File.exists? predicate instead if the file might legitimately be a directory or other special file, or if you plan to create a file by that name if it doesn't exist. File.exists? will return true if a file of the given name exists, no matter what kind of file it is.
directory_name = 'a_directory' FileUtils.mkdir(directory_name) File.file? directory_name # => false File.exists? directory_name # => true
Discussion
A true response from File.exists? means that the file is present on the filesystem, but says nothing about what type of file it is. If you open up a directory thinking it's a regular file, you're in for an unpleasant surprise. This is why File.file? is usually more useful than File.exists?.
Ruby provides several other predicates for checking the type of a file: the other commonly useful one is File.directory?:
File.directory? directory_name # => true File.directory? filename # => false
The rest of the predicates are designed to work on Unix systems. File.blockdev? tests or block-device files (such as hard-drive partitions), File.chardev? tests for character-device files (such as TTYs), File.socket? tests for socket files, and File.pipe? tests for named pipes,
File.blockdev? '/dev/hda1' # => true File.chardev? '/dev/tty1' # => true File.socket? '/var/run/mysqld/mysqld.sock' # => true system('mkfifo named_pipe') File.pipe? 'named_pipe' # => true
File.symlink? tests whether a file is a symbolic link to another file, but you only need to use it when you want to treat symlinks differently from other files. A symlink to a regular file will satisfy File.file?, and can be opened and used just like a regular file. In most cases, you don't even have to know it's a symlink. The same goes for symlinks to directories and to other types of files.
new_filename = "#{filename}2" File.symlink(filename, new_filename) File.symlink? new_filename # => true File.file? new_filename # => true
All of Ruby's file predicates return false if the file doesn't exist at all. This means you can test "exists and is a directory" by just testing directory?; it's the same for the other predicates.
See Also
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration