2013-07-07 52 views
1

我有这样的下面的方法来获取目录的字节大小:获取与门槛目录大小

public static long GetDirectorySize(string folderPath) 
    { 
     DirectoryInfo di = new DirectoryInfo(folderPath); 
     return di.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); 
    } 

我想补充以下功能 - 如果目录的大小大于500 MB(或任何输入数字),我希望它返回-1;

我可以很容易地通过改变返回来实现它:

var size = di.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length) 
return (size <= 500*1024) ? size : -1; 

,因为它越过在.Sum(fi => fi.Length)所有文件这不是高雅的,也没有效率。

有没有一个优雅的方式来添加功能,允许来电添加阈值?

注:我试图避免遍历所有的文件,如果有一个文件夹中有100,000个文件,第一个大于500 MB,没有继续迭代的重点。

+0

你可以()''使用与TakeWhile副作用。 – SLaks

+0

这是否意味着你想在磁盘上的大小而不是目录的大小?或者这两者在你所需要的方面可以忽略不计? – keyboardP

+0

@keyboardP,我想磁盘上目录的大小。 但是,如果它超过某个阈值,我想返回-1。 我不想迭代停止迭代一旦达到此阈值。 – Ofiris

回答

2

你可以滥用LINQ有副作用的做到这一点:

int totalSize = 0; 
directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories) 
    .TakeWhile(fi => (totalSize += fi.Length) < threshold) 
    .Count();  // Force query to execute 

return (totalSize <= threshold) ? totalSize : -1; 
+0

看起来不错,你能解释一下副作用是什么意思吗? – Ofiris

+1

@Ofiris:这个lambda表达式会影响其自身之外的事情,所以多次调用它会破坏您的代码。 LINQ回调应该是纯粹的。 http://en.wikipedia.org/wiki/Pure_function – SLaks

+0

谢谢你的解释和答案,我有一个解决方案提升的问题,'totalSize'没有更新...我不得不'.Sum'的枚举结果..很高兴知道'TakeWhile' – Ofiris

0

在你的方法,你可以指定一个可选的参数设置为0,所以如果你输入一些值将被设置为该值,否则将是500MB。的方法转换字节MB和返回-1,如果值高于和1,如果少:

编辑:

public static int GetDirectorySize(string folderPath,int userinput = 0) 
{ 
    double threshold = userinput == 0 ? 500 : userinput; 
    DirectoryInfo di = new DirectoryInfo(folderPath); 
    double temp = (di.EnumerateFiles("*", SearchOption.AllDirectories).TakeWhile(fl => (fl.Length/1024f)/1024f <= threshold).Sum(fi => fi.Length)/1024f)/1024f; 
    temp = Math.Round(temp, 2); 
    if (temp >= threshold) 
    { 
     return -1; 
    } 
    else 
    { 
     return 1; 
    } 
    // or return temp > threshold ? -1 : 1; 
} 
+0

想一个案例,我有一个文件夹中有100,000个文件,第一个是501 MB,我想避免迭代100,000个文件。 – Ofiris