How to Traverse a Directory

N

Newbie

def traverse(root)
Dir.foreach(root) do |file|
next if file[0] == ?.
puts file
traverse(root + '\\' + file) if File.directory?(root + '\\' + file)
end
end

This is my initial attempt. Two things feel rather wrong:
1) Is there a simpler way to test the beginning of a string? A startsWith?(aString) like method?
2) I'm iterating through filenames, then appending the path each time. Is there a way to get a
collection of File objects from a directory?

Any other pointers to where I could improve would also be greatly appreciated.

(I tried posting this twice through Teranews, but it doesn't seem to have got through.)
 
M

Marc Heiler

Cant really help you but just want to say that
next if file[0] == ?.

is something I did too to get rid of the . and .. which
dont really give me helpful info (when i look for real
files or directories for example)
 
M

MonkeeSage

Newbie said:
def traverse(root)
Dir.foreach(root) do |file|

You can use Dir #[], #glob, or #entries also. If you use a glob or the
entries method, you can also automatically skip the . and .. --
Dir.entries(root)[2..-1] will give you an array of all the files and
subdirs in root, minus the first two (which are always . and ..) If you
do that, you can skip the next line.

Check out the docs to see how to use them further:
http://ruby-doc.org/core/classes/Dir.html
next if file[0] == ?.

This will probably work for most cases in windows (though not always),
but it definitely a bad idea for any other OS (because filenames can
start with a . to mean they should be hidden in normal listing modes).
What I usually use is -- next if ['.', '..'].include? file -- which
checks if the full filename == '.' or '..'
puts file
traverse(root + '\\' + file) if File.directory?(root + '\\' + file)

This is also not very portable. Better to use File.join(root, file)

Ps. Your directory traverser looks ALOT better than my first one did!

HTH,
Jordan
 
M

MonkeeSage

MonkeeSage said:
This is also not very portable. Better to use File.join(root, file)

You can also refactor that to this:

puts file = File.join(root, file) # assignment returns its value
traverse(file) if File.directory?(file)
 
R

Robert Klemme

def traverse(root)
Dir.foreach(root) do |file|
next if file[0] == ?.
puts file
traverse(root + '\\' + file) if File.directory?(root + '\\' + file)
end
end

This is my initial attempt. Two things feel rather wrong:
1) Is there a simpler way to test the beginning of a string? A
startsWith?(aString) like method?

Like this?
next if /^\./ =~ file
2) I'm iterating through filenames, then appending the path each time.
Is there a way to get a collection of File objects from a directory?

File objects are for actually reading and writing objects. You can do
Dir["*"] which returns an array of strings.
Any other pointers to where I could improve would also be greatly
appreciated.

Use Find:

irb(main):001:0> require 'find'
=> true
irb(main):002:0> Find.find('.') {|f| puts f}
..
../x
../prj-jar.txt
../jdk-jar.txt
=> nil

irb(main):005:0> Find.find('/tmp') {|f| puts f}
/tmp
/tmp/x
/tmp/prj-jar.txt
/tmp/jdk-jar.txt
=> nil

irb(main):008:0> Find.find '/tmp' do |f|
irb(main):009:1* next if File.directory? f
irb(main):010:1> puts f
irb(main):011:1> end
/tmp/x
/tmp/prj-jar.txt
/tmp/jdk-jar.txt

Note, you can also use File.join to portably combine paths.

Kind regards

robert
 
N

Newbie

MonkeeSage said:
next if file[0] == ?.

This will probably work for most cases in windows (though not always),
but it definitely a bad idea for any other OS (because filenames can
start with a . to mean they should be hidden in normal listing modes).
What I usually use is -- next if ['.', '..'].include? file -- which
checks if the full filename == '.' or '..'

Good point - perhaps http://www.ruby-doc.org/core/classes/Find.html should be fixed ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top