Checking to See If a File Exists

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

  • Recipe 6.8, "Writing to a Temporary File," and Recipe 6.14, "Backing Up to Versioned Filenames," deal with writing to files that don't currently exist


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



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net