C#文件和目录迭代,可以同时进行吗?

C#文件和目录迭代,可以同时进行吗?,c#,directoryinfo,C#,Directoryinfo,这可能是一个令人困惑的问题,但我在下面写了一个目录爬虫,它将从根爬虫开始,找到所有唯一的目录,然后找到所有的文件,对它们进行计数,并计算它们的文件大小。然而,我编写它的方式需要去目录两次,一次查找目录,下一次清点文件。如果/如何一次获得所有信息 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); HashSet<string> DirectoryHolding = new H

这可能是一个令人困惑的问题,但我在下面写了一个目录爬虫,它将从根爬虫开始,找到所有唯一的目录,然后找到所有的文件,对它们进行计数,并计算它们的文件大小。然而,我编写它的方式需要去目录两次,一次查找目录,下一次清点文件。如果/如何一次获得所有信息

       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());
                }
            }
        }
.26秒我认为这是赢家

您可以使用:

或者(这可能更有效,因为已经有了所需的大部分信息,您可以跳过
文件.Exists
检查):


通常的方法是编写递归方法。这里是伪代码:

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;
}

提示:您不需要这样做:
if(FindAllDirectoriesbool==true)
这将正常工作:
if(FindAllDirectoriesbool)
使用
目录。枚举文件
或递归。@M.Babcock这将如何加快速度,它当然不是foreach循环,但不是相同的速度吗?我认为这里的网络连通性是瓶颈,而不是code@M.Babcock我仍然需要做GetDirectories来知道哪些目录是nextI当然可以修改这里的代码,但是如何改变仍然查找和放置所有目录,然后返回这些目录的问题呢?我不想粗鲁我只是不明白,我必须找到所有的“条目”才能告诉他们信不信由你,这种方法比我上面的两种方法都慢30%,发布方法:stopwatch.appeased.TotalMinutes=1.35上面提到的方法:=stopwatch.appeased.TotalMinutes 1.88如何获得else语句中的文件大小?我测试了第二种方法,如果我必须使用FileInfo,大约需要1.7秒,我不必使用FileInfo,需要10秒,因此,如果我可以在不再次调用fileinfo的情况下获取文件大小,那将是一件了不起的事情,您必须手动获取它-更准确的信息,但可能比通过
DirectoryInfo.GetFiles
(无法击败缓存信息):
long filesize=new fileinfo(entry.Name).Length
var entries = Directory.EnumerateFileSystemEntries(rootDirectory);
foreach (var entry in entries)
{
    if(File.Exists(entry))
    {
        //file
    }
    else
    {
        //directory
    }
}
var entries = new DirectoryInfo(rootDirectory).EnumerateFileSystemInfos();
foreach (var entry in entries)
{
    if ((entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
    {
        //direcotry
    }
    else
    {
        //file
    }
}
void ProcessDirectory(Dir directory)
{
    foreach (var file in directory.Files)
        ProcessFile(file);

    foreach (var child in directory.Subdirectories)
        ProcessDirectory(directory);
}
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;
}