5

これは紛らわしい質問かもしれませんが、ルートクローラーから開始し、すべての一意のディレクトリを見つけてから、すべてのファイルを見つけてそれらを数え、ファイルサイズを合計するディレクトリクローラーの下に書きました。ただし、私が書いた方法では、ディレクトリに 2 回アクセスする必要があります。1 回目はディレクトリを検索し、2 回目はファイルをカウントします。すべての情報を一度に取得できる場合/どのように可能ですか?

       Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        HashSet<string> DirectoryHolding = new HashSet<string>();
        DirectoryHolding.Add(rootDirectory);


        #region All Directory Region
        int DirectoryCount = 0;
        int DirectoryHop = 0;
        bool FindAllDirectoriesbool = true;
        while (FindAllDirectoriesbool == true)
        {
            string[] DirectoryHolder = Directory.GetDirectories(rootDirectory);
            if (DirectoryHolder.Length == 0)
            {
                if (DirectoryHop >= DirectoryHolding.Count())
                {
                    FindAllDirectoriesbool = false;
                }
                else
                {
                    rootDirectory = DirectoryHolding.ElementAt(DirectoryHop);
                }
                DirectoryHop++;
            }
            else
            {
                foreach (string DH in DirectoryHolder)
                {
                    DirectoryHolding.Add(DH);
                }
                if (DirectoryHop > DirectoryHolding.Count())
                {
                    FindAllDirectoriesbool = false;
                }
                rootDirectory = DirectoryHolding.ElementAt(DirectoryHop);
                DirectoryHop++;

            }

        }
        DirectoryCount = DirectoryHop - 2;
        #endregion



        #region File Count and Size Region
        int FileCount = 0;
        long FileSize = 0;
        for (int i = 0; i < DirectoryHolding.Count ; i++)
        {
            string[] DirectoryInfo = Directory.GetFiles(DirectoryHolding.ElementAt(i));
            for (int fi = 0; fi < DirectoryInfo.Length; fi++)
            {
                try
                {
                    FileInfo fInfo = new FileInfo(DirectoryInfo[fi]);
                    FileCount++;
                    FileSize = FileSize + fInfo.Length;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message.ToString());
                }
            }
        }

このストップウォッチの結果は 1.38 です

int FileCount = 0;
        long FileSize = 0;
        for (int i = 0; i < DirectoryHolding.Count; i++)
        {
            var entries = new DirectoryInfo(DirectoryHolding.ElementAt(i)).EnumerateFileSystemInfos();
            foreach (var entry in entries)
            {
                if ((entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    DirectoryHolding.Add(entry.FullName);
                }
                else
                {
                    FileCount++;
                    FileSize = FileSize + new FileInfo(entry.FullName).Length;
                }
            }
        }

このメソッドのストップ ウォッチは 2.01 です。

これは私には意味がありません。

 DirectoryInfo Dinfo = new DirectoryInfo(rootDirectory);
            DirectoryInfo[] directories = Dinfo.GetDirectories("*.*", SearchOption.AllDirectories);
            FileInfo[] finfo = Dinfo.GetFiles("*.*", SearchOption.AllDirectories);
            foreach (FileInfo f in finfo)
            {
                FileSize = FileSize + f.Length;
            }
            FileCount = finfo.Length;
            DirectoryCount = directories.Length; 

.26秒 これが勝者だと思う

4

2 に答える 2

8

使用できますDirectory.EnumerateFileSystemEntries()

var entries = Directory.EnumerateFileSystemEntries(rootDirectory);
foreach (var entry in entries)
{
    if(File.Exists(entry))
    {
        //file
    }
    else
    {
        //directory
    }
}

または、代わりに (これは、必要な情報のほとんどが既に含まれており、チェックをスキップできるDirectoryInfo.EnumerateFileSystemInfos()ため、よりパフォーマンスが高い可能性があります):FileSystemInfoFile.Exists

var entries = new DirectoryInfo(rootDirectory).EnumerateFileSystemInfos();
foreach (var entry in entries)
{
    if ((entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
    {
        //direcotry
    }
    else
    {
        //file
    }
}
于 2012-03-28T18:22:01.943 に答える
2

通常のアプローチは、再帰的なメソッドを記述することです。ここに疑似コードがあります:

void ProcessDirectory(Dir directory)
{
    foreach (var file in directory.Files)
        ProcessFile(file);

    foreach (var child in directory.Subdirectories)
        ProcessDirectory(directory);
}

foreach ループの順序を逆にすることもできます。たとえば、再帰的な方法ですべてのファイルの合計サイズを計算するには、次のようにします。

int GetTotalFileSize(Dir directory)
{
    ulong result = 0UL;

    foreach (var child in directory.Subdirectories)
        result += GetTotalFileSize(directory);

    foreach (var file in directory.Files)
        result += file.Length;

    return result;
}
于 2012-03-28T18:32:17.267 に答える