8

単純な再帰的アプローチを使用して、より大きなプログラムの一部に Ruby でディレクトリ トラバーサルを実装しようとしています。ただし、Dir.foreachにはその中にディレクトリが含まれていないことがわかりました。それらを一覧表示するにはどうすればよいですか?

コード:

def walk(start)
  Dir.foreach(start) do |x|
    if x == "." or x == ".."
      next
    elsif File.directory?(x)
      walk(x)
    else
      puts x
    end
  end
end
4

2 に答える 2

16

問題は、再帰するたびに、渡すパスFile.directory?が単なるエンティティ (ファイルまたはディレクトリ) 名であることです。すべてのコンテキストが失われます。つまり、トップレベルのディレクトリの観点から、ディレクトリであるone/two/three/かどうかを確認すると、全体ではなくパスとして取得されます。再帰するたびに相対パスを維持する必要があります。これはうまくいくようです:one/two/three/file.txtFile.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
于 2013-03-29T05:51:27.163 に答える
15

再帰にはFindを使用する必要があります。

ドキュメントから:

検索モジュールは、一連のファイル パスのトップダウン トラバーサルをサポートします。

たとえば、「ドット」ディレクトリ (例: $HOME/.ssh) 内のものを無視して、ホーム ディレクトリの下にあるすべてのファイルのサイズを合計するには、次のようにします。

「検索」が必要

合計サイズ = 0

Find.find(ENV["HOME"]) do |パス|
  if FileTest.directory?(パス)
    if File.basename(path)[0] == ?.
      Find.prune # このディレクトリをこれ以上調べないでください。
    そうしないと
      次
    終わり
  そうしないと
    total_size += FileTest.size(パス)
  終わり
終わり
于 2013-03-29T05:58:52.597 に答える