The Find module supports the top-down traversal of a set of file paths.
For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):
require 'find' total_size = 0 Find.find(ENV["HOME"]) do |path| if FileTest.directory?(path) if File.basename(path)[0] == ?. Find.prune # Don't look any further into this directory. else next end else total_size += FileTest.size(path) end end
Calls the associated block with the name of every file and directory listed as arguments, then recursively on their subdirectories, and so on.
See the Find module documentation for an example.
# File find.rb, line 35
def find(*paths) # :yield: path
block_given? or return enum_for(__method__, *paths)
paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
while file = paths.shift
catch(:prune) do
yield file.dup.taint
begin
s = File.lstat(file)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
next
end
if s.directory? then
begin
fs = Dir.entries(file)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
next
end
fs.sort!
fs.reverse_each {|f|
next if f == "." or f == ".."
f = File.join(file, f)
paths.unshift f.untaint
}
end
end
end
end
Skips the current file or directory, restarting the loop with the next entry. If the current file is a directory, that directory will not be recursively entered. Meaningful only within the block associated with Find::find.
See the Find module documentation for an example.
# File find.rb, line 72
def prune
throw :prune
end