Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > How to Traverse a Directory

Reply
Thread Tools

How to Traverse a Directory

 
 
Newbie
Guest
Posts: n/a
 
      09-21-2006
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.)
 
Reply With Quote
 
 
 
 
Marc Heiler
Guest
Posts: n/a
 
      09-21-2006
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)

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
MonkeeSage
Guest
Posts: n/a
 
      09-21-2006
Newbie wrote:
> 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)

> end
> end


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

HTH,
Jordan

 
Reply With Quote
 
MonkeeSage
Guest
Posts: n/a
 
      09-21-2006

MonkeeSage wrote:
> > puts file
> > traverse(root + '\\' + file) if File.directory?(root + '\\' + file)

>
> 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)

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      09-21-2006
On 21.09.2006 11:06, Newbie wrote:
> 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
 
Reply With Quote
 
Newbie
Guest
Posts: n/a
 
      09-21-2006
Thanks for all the help!

MonkeeSage wrote:
<stuff>
 
Reply With Quote
 
Newbie
Guest
Posts: n/a
 
      09-21-2006
MonkeeSage wrote:
>> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
noob question:traverse directory and populate mysql db jay Ruby 0 02-01-2007 09:52 AM
traverse directory with boost Gary Wessle C++ 4 08-06-2006 08:40 AM
Traverse a directory weberw@adelphia.net Perl Misc 11 07-15-2006 04:10 PM
traverse a directory and subdirectories to find files ' properties Thieum22 Perl 1 08-06-2004 08:01 PM



Advertisments