2

以下の方法で、ルートディレクトリのすべてのサブディレクトリにあるファイルを一覧表示しようとしています。しかし、ファイルの数が数百万になると、かなりの時間がかかります。これを行うためのより良いアプローチはありますか?

.NET 3.5を使用しているため、列挙子を使用できません:-(

        ******************* Main *************
        DirectoryInfo dir = new DirectoryInfo(path);
        DirectoryInfo[] subDir = dir.GetDirectories();
        foreach (DirectoryInfo di in subDir) //call for each sub directory
        {
             PopulateList(di.FullName, false);
        }

        *******************************************
        static void PopulateList(string directory, bool IsRoot)
        {

            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + "dir /s/b \"" + directory + "\"");
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();

            string fileName = directory.Substring(directory.LastIndexOf('\\') + 1);
            StreamWriter writer = new StreamWriter(fileName + ".lst");

            while (proc.StandardOutput.EndOfStream != true)
            {
                 writer.WriteLine(proc.StandardOutput.ReadLine());
                 writer.Flush();
            }
            writer.Close();
        }
4

5 に答える 5

2

プロセス関連のものをすべて削除し、Directory.GetDirectories()メソッドとDirectory.GetFiles ()メソッドを試してください。

public IEnumerable<string> GetAllFiles(string rootDirectory)
{
    foreach(var directory in Directory.GetDirectories(
                                            rootDirectory, 
                                            "*", 
                                            SearchOption.AllDirectories))
    {
        foreach(var file in Directory.GetFiles(directory))
        {
            yield return file;
        }
    }
}

MSDNから、SearchOption.AllDirectories:

現在のディレクトリとすべてのサブディレクトリを検索操作に含めます。このオプションには、マウントされたドライブやシンボリックリンクなどの再解析ポイントが検索に含まれます。

于 2011-09-29T11:41:32.080 に答える
1

DirectoryInfo.GetFiles大量の新しいプロセスを生成して出力を読み取るのではなく、各ディレクトリのループで使用する方が間違いなく高速です。

于 2011-09-29T11:43:38.823 に答える
1

何百万ものファイルで実際にファイルシステムの制限に直面しているので(これを参照して「300,000」を検索してください)、これを考慮に入れてください。

最適化に関しては、本当に怠惰に繰り返したいと思うので、P / Invokeinto/にする必要がありFindFirstFileますFindNextFile

于 2011-09-29T11:44:56.727 に答える
0

すでに利用可能なDirectory.GetFilesオーバーロードを確認してください。
例えば:

var paths = Directory.GetFiles(root, "*", SearchOption.AllDirectories);

そして、はい、それは多くの時間がかかります。しかし、.Netクラスだけを使用してパフォーマンスを向上させることはできないと思います。

于 2011-09-29T11:41:31.070 に答える
0

数百万のファイルが複数のサブディレクトリに分散していて、.NET 4.0を使用していると仮定すると、並列拡張機能を確認できます。

並列foreachループを使用してサブディレクトリのリストを処理すると、処理が大幅に高速化される可能性があります。

新しい並列拡張機能は、下位レベルでマルチスレッドを試行するよりもはるかに安全で使いやすくなっています。

注意すべきことの1つは、並行プロセスの数を適切なものに制限することです。

于 2011-09-29T11:51:01.303 に答える