获取目录大小的更有效方法

ika*_*eat 8 c# directory recursion search

我已经构建了一个递归函数来获取文件夹路径的目录大小.它的工作原理,但随着我必须搜索的目录数量不断增加(以及每个相应文件夹中的文件数量),这是一种非常缓慢,低效的方法.

static string GetDirectorySize(string parentDir)
{
    long totalFileSize = 0;

    string[] dirFiles = Directory.GetFiles(parentDir, "*.*", 
                            System.IO.SearchOption.AllDirectories);

    foreach (string fileName in dirFiles)
    {
        // Use FileInfo to get length of each file.
        FileInfo info = new FileInfo(fileName);
        totalFileSize = totalFileSize + info.Length;
    }
    return String.Format(new FileSizeFormatProvider(), "{0:fs}", totalFileSize);
}
Run Code Online (Sandbox Code Playgroud)

这是在所有子目录中搜索参数路径,因此dirFiles数组变得非常大.有没有更好的方法来实现这一目标?我已经四处寻找,但还没有找到任何东西.

我想到的另一个想法是将结果放入缓存中,当再次调用该函数时,尝试查找差异并仅重新搜索已更改的文件夹.不确定这是不是一件好事......

usr*_*usr 25

您首先扫描树以获取所有文件的列表.然后,您将重新打开每个文件以获得其大小.这相当于扫描两次.

我建议你用DirectoryInfo.GetFiles它来FileInfo直接递给你.这些物体预先填充了它们的长度.

.NET 4中,您还可以使用EnumerateFiles将返回惰性的方法IEnumable.


pap*_*zzo 12

尝试

        DirectoryInfo DirInfo = new DirectoryInfo(@"C:\DataLoad\");
        Stopwatch sw = new Stopwatch();
        try
        {
            sw.Start();
            Int64 ttl = 0;
            Int32 fileCount = 0;
            foreach (FileInfo fi in DirInfo.EnumerateFiles("*", SearchOption.AllDirectories))
            {
                ttl += fi.Length;
                fileCount++;
            }
            sw.Stop();
            Debug.WriteLine(sw.ElapsedMilliseconds.ToString() + " " + fileCount.ToString());
        }
        catch (Exception Ex)
        {
            Debug.WriteLine(Ex.ToString());
        }
Run Code Online (Sandbox Code Playgroud)

这在台式机NON-RAID P4上在70秒内完成了70万次.所以像每秒10,000.在服务器类机器上应该容易获得100,000+ /秒.

正如usr(+1)所说,EnumerateFile预先填充了长度.


MrF*_*Fox 11

这更加神秘,但10k执行需要大约2秒钟.

    public static long GetDirectorySize(string parentDirectory)
    {
        return new DirectoryInfo(parentDirectory).GetFiles("*.*", SearchOption.AllDirectories).Sum(file => file.Length);
    }
Run Code Online (Sandbox Code Playgroud)

  • \*.\*会遗漏一些文件 (9认同)
  • 为清楚起见,.Sum()需要System.Linq (2认同)