2013-03-29 48 views
4

我一直试图在Ruby中使用简单的递归方法实现一个更大程序的部分目录遍历。但是我发现Dir.foreach不包括它里面的目录。我怎样才能让他们上市?Ruby中的目录遍历

代码:

​​
+0

代替'Dir.foreach',你可以使用'Dir.glob(start)'或者'Dir [start]'。 –

+0

你想跳过'.'和'..'吗?并且想要在'walk(start)'的每个调用中的'start'中遍历其他人? –

+0

@iAmRubuuu是的,以避免无限递归。 – squiguy

回答

11

的问题是,每次递归的时候,你传递给File.directory?的路径是不只是实体(文件或目录)的名称;所有上下文都会丢失。因此,假设你进入one/two/three/来检查one/two/three/file.txt是否是一个目录,File.directory?只是从顶层目录的角度将"file.txt"作为路径而不是整个事物。每次你递归时你都必须保持相对路径。这似乎很好地工作:

def walk(start) 
    Dir.foreach(start) do |x| 
    path = File.join(start, x) 
    if x == "." or x == ".." 
     next 
    elsif File.directory?(path) 
     puts path + "/" # remove this line if you want; just prints directories 
     walk(path) 
    else 
     puts x 
    end 
    end 
end 
+1

是的,它根本不打印任何东西。我一直在玩它一段时间。 – squiguy

+0

@squiguy奇怪,我只是自己试了一下,它确实有效。 –

+0

它是否在每个目录内?我觉得我做错了什么。我不怀疑你! – squiguy

10

递归你应该使用Find

从文档:

的查找模块支持一组文件路径的自顶向下穿越。

例如,以总价所有文件的大小,你的主目录下,在一个“点”目录忽略任何东西(如$ 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 
+1

很好找。我从来不知道这件事。 – squiguy

1

尝试以下:

​​
+0

这不会递归地遍历目录。目录检查需要路径,并且该路径应该在递归调用中传递,以便后续的Dir.entries调用工作。 x = File.join(start,x)应该遵循Dir.entries .... –