4

ディレクトリとサブフォルダーを列挙して列挙内のすべてのファイルを収集するより高速な方法を知っている人はいますか? これは私が今持っているものです:

Public Shared allFiles() As String
allFiles = Directory.GetFiles(<ServerLocation>, "*.*", SearchOption.AllDirectories)

ありがとう!JFV

編集: サーバーの場所からこれらのファイルを列挙しています。それがこの質問の見方を変えるかどうかはわかりません。これまでのすべての入力に感謝します!

4

4 に答える 4

4

簡潔な答え:

このコードがプロジェクトに対して機能的に正しく、プロファイラーの問題であることが証明されていない場合は、変更しないでください。遅いことが証明されるまで、機能的に正しいソリューションを使用し続けます。

長い答え:

この特定のコードがどれだけ速いか遅いかは、多くの要因によって異なります。その多くは、実行している特定のマシンに依存します (たとえば、ハード ドライブの速度)。ファイルシステムだけが関係するコードを見ると、「x は y より速い」と断言するのは非常に困難です。

この場合、私が実際にコメントできることは 1 つだけです。このメソッドの戻り値の型は、FileInfo 値の配列です。配列には連続したメモリが必要であり、配列が非常に大きいと、ヒープで断片化の問題が発生する可能性があります。読み込んでいるディレクトリが非常に大きい場合、ヒープの断片化が発生し、間接的にパフォーマンスの問題が発生する可能性があります。

それが問題であることが判明した場合は、FindFirstFile / FindNextFile に PInvoke して、一度に 1 つずつ取得できます。その結果、CPU サイクルが機能的に遅くなる可能性がありますが、メモリ負荷は少なくなります。

しかし、修正する前に、これらが問題であることを証明する必要があることを強調しなければなりません。

于 2009-06-28T04:39:26.003 に答える
3

System.Collections.Generic の使用;

private static List<string> GetFilesRecursive(string b)
{

             // 1.
            // Store results in the file results list.
            List<string> result = new List<string>();

            // 2.
            // Store a stack of our directories.
            Stack<string> stack = new Stack<string>();

            // 3.
            // Add initial directory.
            stack.Push(b);

            // 4.
            // Continue while there are directories to process
            while (stack.Count > 0)
            {
                // A.
                // Get top directory
                string dir = stack.Pop();

                try
                {
                    // B
                    // Add all files at this directory to the result List.
                    result.AddRange(Directory.GetFiles(dir, "*.*"));

                    // C
                    // Add all directories at this directory.
                    foreach (string dn in Directory.GetDirectories(dir))
                    {
                        stack.Push(dn);
                    }
                }
                catch
                {
                    // D
                    // Could not open the directory
                }
            }
            return result;
        }

元の記事への小道具: http://www.codeproject.com/KB/cs/workerthread.aspx

于 2010-11-16T15:41:45.140 に答える
0

これが私の解決策です。最初の起動は少し遅いです、私はそれに取り組んでいます。my.computer.filesystem オブジェクトは、おそらく起動が遅い問題です。しかし、この方法では、ネットワーク経由で 5 分以内に 31,000 個のファイルが一覧表示されます。

Imports System.Threading

Public Class ThreadWork

Public Shared Sub DoWork()
    Dim i As Integer = 1
    For Each File As String In My.Computer.FileSystem.GetFiles("\\172.16.1.66\usr2\syscon\S4_650\production\base_prog", FileIO.SearchOption.SearchTopLevelOnly, "*.S4")
        Console.WriteLine(i & ". " & File)
        i += 1
    Next
End Sub 'DoWork
End Class 'ThreadWork

Module Module1

Sub Main()
    Dim myThreadDelegate As New ThreadStart(AddressOf ThreadWork.DoWork)
    Dim myThread As New Thread(myThreadDelegate)
    myThread.Start()
    '"Pause" the console to read the data.
    Console.ReadLine()
End Sub 'Main

End Module
于 2011-12-06T14:05:34.133 に答える
0

これは大雑把なやり方です。

dir /s /b

この出力をテキスト ファイルに取得し、それを読み取って で分割し\r\nます。
上記のコマンドを特定のディレクトリで実行して、役立つかどうかを確認します。

ディレクトリのみを取得するには

dir /s /b /ad

ファイルのみを取得するには

dir /s /b /a-d

編集: Jared は、アプローチが遅いことが証明されない限り、他のアプローチを使用しないと言っているのは正しいです。

于 2009-06-28T05:40:14.803 に答える