我正在編寫一個32位的c#應用程序,通過從kernal32.dll FindFirstFile獲取文件信息來返回目錄的總體大小。這已經勝過以常規方式枚舉每個目錄,並且我能夠保持資源使用非常低。應用程序之間的Windows目錄大小差異
是如何工作的快速概述如下:
- 第1步 - 枚舉根目錄下得到所有子目錄和使用,以用FindFirstFile收集這個目錄下的每個文件大小信息。
- 步驟2 - 產生子線程(最多20個)對子目錄執行步驟1
- 步驟3 - 遞歸到目錄耗盡並且已收集所有文件信息。
這可以在以下代碼示例中看到,其中FileSystem.GetFiles是我的類,它使用kernal32方法獲取文件信息。
private static void recurseDirectories(string directoryA, bool paramInitialPass)
{
try
{
string[] currentDirs;
if (paramInitialPass)
{
currentDirs = new string[1];
currentDirs[0] = rootDirectory;
}
else
currentDirs = Directory.GetDirectories(directoryA);
for (int i = 0; i < currentDirs.Length; i++)
{
string threadInfo = currentDirs[i];
numThreadsQueued++;
ThreadPool.QueueUserWorkItem(new WaitCallback(getDirectoryFileInformation), (object)threadInfo);
while (numThreadsQueued - directoriesProcessed > 20)
{
Thread.Sleep(30);
}
if (paramInitialPass)
recurseDirectories(directoryA, false);
else
recurseDirectories(currentDirs[i], false);
}
}
catch
{
}
return;
}
private static void getDirectoryFileInformation(object paramDirectoryFilePathA)
{
try
{
string directoryPathA = (string)paramDirectoryFilePathA;
List<FileData> filesDirectoryA = new List<FileData>();
if (Directory.Exists(directoryPathA))
{
filesDirectoryA = FileSystem.GetFiles(directoryPathA);
}
foreach(FileData file in filesDirectoryA)
{
Interlocked.Add(ref sizeOfFiles, file.Size);
Interlocked.Increment(ref numberOfFiles);
}
}
catch (Exception e)
{
}
finally
{
Interlocked.Increment(ref directoriesProcessed);
}
}
這兩種方法是使用下面的代碼名爲:
ThreadPool.SetMaxThreads(30, 500);
Thread.CurrentThread.Priority = ThreadPriority.Normal;
rootDirectory = share["Path"].ToString();
recurseDirectories(share["Path"].ToString(), true);
while (numThreadsQueued != directoriesProcessed)
{
Thread.Sleep(1000);
}
此代碼已經表現堪稱完美,而枚舉大多數目錄。我可以在大約8分鐘內恢復3TB文件共享,獲得總文件大小和文件數量,同時保持CPU低於3%並使用15MB內存。
既然說到這個問題......
當得到尺寸小目錄(1-200 GB)我看不出什麼,從窗戶往外看的目錄屬性時說,任何重大差異。然而,我已經注意到,在獲得大型目錄的大小(2-3TB)時有一些重大差異。
例如:
說我在看目錄d:\ TESTDIR這是DFSR複製到另一臺服務器。 Windows說這個目錄是2,949,944,019,217字節,或磁盤上的2,974,186,774,528字節(分別是2.68TB或2.70TB)。 我的程序說這個目錄是3,009,619,048,759字節或2.737 TB。 FSRM表示同一目錄上的配額設置有2.71 TB的使用量。
我知道這種差異部分是由於Windows不包含隱藏文件的大小,但是當我將目錄(87GB)中的隱藏文件的總大小添加到Windows值時,我得到了〜2.78 GB,這仍然不同從我的價值。任何人都可以闡明我還有什麼可以導致這些尺寸差異?另外,有誰知道FSRM如何確定配額使用情況?
最後我想用我的數據替換監視系統的FSRM配額,但是如果我的數據不符合Windows的說法,我可能會在磁盤使用情況下獲得虛假警報。
根本沒有看過它,但是對於小文件,一個是報告數據的實際大小,另一個是報告分配磁盤空間的大小?我相信一個文件的最小分配大小是4K,不管數據有多少。 – Bobson
感謝Bobson的評論,我確信Windows的「磁盤大小」將此考慮在內,從而產生2.70 TB的值。我這樣說是因爲如果您查看4K以下文件的屬性,它會說「大小:x字節,磁盤上的大小:4.00 KB」) – vesuvious