c# - example - wpf filelist




C#で20,000以上のファイルを持つディレクトリ内のファイルを探す最も速い方法 (4)

GetFilesを実行して無差別な検索を行うのではなく、最初に「最初のサブフォルダ」のリストを取得し、それらのディレクトリをループし、サブフォルダの処理を繰り返し、最後にルック・バックしてGetDirectoriesを使用しますxmlフォルダを検索し、最後に.xmlファイルを検索します。

さて、パフォーマンスに関しては、この速度は変わりますが、ディレクトリを最初に検索してから、ファイルにアクセスすると多くの手助けが必要になります。

更新

さて、私はテストの迅速なビットをし、あなたが思ったよりもはるかにそれを実際に最適化することができます。

次のコードスニペットは、ディレクトリ構造を検索し、ディレクトリツリー全体のすべての "xml"フォルダを検索します。

string startPath = @"C:\Testing\Testing\bin\Debug";
string[] oDirectories = Directory.GetDirectories(startPath, "xml", SearchOption.AllDirectories);
Console.WriteLine(oDirectories.Length.ToString());
foreach (string oCurrent in oDirectories)
    Console.WriteLine(oCurrent);
Console.ReadLine();

それをテストコンソールアプリにドロップすると、結果が出力されます。

さて、一度これを取得したら、見つかった各ディレクトリの.xmlファイルを調べてください。

私は、ルートの下に20,000を超えるサブフォルダを持つディレクトリからXMLファイルを引き出すために毎晩実行する仕事を持っています。 構造は次のようになります。

rootFolder/someFolder/someSubFolder/xml/myFile.xml
rootFolder/someFolder/someSubFolder1/xml/myFile1.xml
rootFolder/someFolder/someSubFolderN/xml/myFile2.xml
rootFolder/someFolder1
rootFolder/someFolderN

だから上を見て、構造は常に同じです - ルートフォルダ、次に2つのサブフォルダ、次にxmlディレクトリ、およびxmlファイル。 rootFolderとxmlディレクトリの名前だけがわかっています。

以下のコードはすべてのディレクトリを通過し、非常に遅いです。 特に、ディレクトリ構造がわかっている場合、どのように検索を最適化できるかについての推奨事項はありますか?

string[] files = Directory.GetFiles(@"\\somenetworkpath\rootFolder", "*.xml", SearchOption.AllDirectories);

xmlフォルダと同じレベルに追加のディレクトリがありますか? もしそうなら、おそらく自分でそれを行い、そのレベルを検索から除外すれば、検索をスピードアップすることができます。

        System.IO.DirectoryInfo root = new System.IO.DirectoryInfo(rootPath);
        List<System.IO.FileInfo> xmlFiles=new List<System.IO.FileInfo>();

        foreach (System.IO.DirectoryInfo subDir1 in root.GetDirectories())
        {
            foreach (System.IO.DirectoryInfo subDir2 in subDir1.GetDirectories())
            {
                System.IO.DirectoryInfo xmlDir = new System.IO.DirectoryInfo(System.IO.Path.Combine(subDir2.FullName, "xml"));

                if (xmlDir.Exists)
                {
                    xmlFiles.AddRange(xmlDir.GetFiles("*.xml"));
                }
            }
        }

Parallel.ForEachを使ってGetFoldersという再帰的メソッドを作成し、変数yourKeywordという名前のすべてのフォルダを見つけyourKeyword

List<string> returnFolders = new List<string>();
object locker = new object();

Parallel.ForEach(subFolders, subFolder =>
{
    if (subFolder.ToUpper().EndsWith(yourKeyword))
    {
        lock (locker)
        {
            returnFolders.Add(subFolder);
        }
    }
    else
    {
        lock (locker)
        {
            returnFolders.AddRange(GetFolders(Directory.GetDirectories(subFolder)));
        }
    }
});

return returnFolders;

私が目にすることができるのは、大きな違いがあることがわかる方法は、強引な強さの狩猟から変えて、サードパーティまたはOSインデックス作成ルーチンを使用して復帰をスピードアップすることです。 そうすれば検索はアプリからオフラインで行われます。

しかし、可能ならば、そのデータを構造化するためのより良い方法を検討することをお勧めします。





file-io