1

約 100,000 個の小さなファイル (各ファイルは約 1kB) を含むディレクトリがあるとします。これらのファイルのリストを取得し、同じ名前で大文字と小文字が異なるファイルを見つけるために反復する必要があります (ファイルは Linux ext4 FS 上にあります)。現在、次のようなコードを使用しています。

   def similar_files_in_folder(file_path, folder, exclude_folders = false)
     files = Dir.glob(file_path, File::FNM_CASEFOLD)
     files_set = files.select{|f| f.start_with?(folder)}
     return files_set unless exclude_folders
     files_set.reject{|entry| File.directory? entry}
   end

   dir_entries = Dir.entries(@directory) - ['.', '..']
   dir_entries.map do |file_name|
     similar_files_in_folder(file_name, @directory)
   end

このアプローチの問題は、スニペットに多くの時間がかかることです!!! 終了する時間。私のシステムでは約数時間です。

Rubyで同じ目標を達成する別の方法はありますか?

制限: @directory に新しいファイルが表示されるため、メモリにファイル リストをロードして、名前を小文字で比較することはできません。そのため、反復ごとに @directory をスキャンする必要があります。

ヒントをありがとう。

4

2 に答える 2

2

私があなたのコードを正しく理解していれば、これはすでにそれらの 100k ファイル名すべての配列を返します:

dir_entries = Dir.entries(@directory) - ['.', '..']
#=> ["foo.txt", "bar.txt", "BAR.txt", ...]

この配列を小文字のファイル名でグループ化します。

dir_entries.group_by(&:downcase)
#=> {"foo.txt"=>["foo.txt"], "bar.txt"=>["bar.txt", "BAR.txt"], ... }

そして、複数回出現するものを選択します。

dir_entries.group_by(&:downcase).select { |k, v| v.size > 1 }
#=> {"bar.txt"=>["bar.txt", "BAR.txt"], ...}
于 2013-08-15T08:29:24.300 に答える