2013-07-07 49 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