2012-07-10 155 views
0

我目前正在創建一個文件掃描程序,它基於特定條件枚舉文件。其中一個掃描選項是排除大於預定義大小的文件。這個規則可以應用於個人目錄和他們的孩子。有沒有更好的方法來查找字典中的子字符串

例如,用戶可以指定一個規則,以便僅從C:\ Users {USERNAME} \ Documents中取得小於1GB的文件。因此,如果用戶決定掃描文檔文件夾中的目錄,可以這樣說:C:\Users\{USERNAME}\Documents\SOMEDIR1\SOMEDIR2\指定的規則應該適用於該目錄,並且只應填充小於或等於1GB大小的文件。

目前我將規則存儲在定義爲Dictionary<string, long> dSizeLimit;的字典中,其中鍵是完整的目錄路徑,值是規則的文件大小(以字節爲單位)。

目前我使用下面的方法來確定一個文件應該從填充的文件列表被忽略:

public void SearchDirectory(DirectoryInfo dir_info, List<string> file_list, ref long size, ScanOptions Opt = null) 
     { 
      if (Opt == null) 
       Opt = DefaultOption; 
      try 
      { 
       foreach (DirectoryInfo subdir_info in dir_info.GetDirectories()) 
       { 
        SearchDirectory(subdir_info, file_list, ref size, Opt); 
       } 
      } 
      catch(Exception ex) 
      { 
       Console.WriteLine("Failed to enumerate directory: {0}", dir_info.FullName); 
       Console.WriteLine("Exception: {0}", ex.Message); 
      } 

      try 
      { 

       foreach (FileInfo file_info in dir_info.GetFiles()) 
       { 
        //Here I iterate over all the size rules to determine if the current file should be added to the file_list 
        foreach (KeyValuePair<string,long> entry in Opt.dSizeLimit) 
        { 
         if(string.Compare(entry.Key, 0, file_info.FullName, 0, entry.Key.Length, true)==0) 
         { 
          if (entry.Value > 0 && file_info.Length > entry.Value) 
           continue; 
         } 
        } 

        file_list.Add(file_info.FullName); 
        size += file_info.Length; 
       } 
      } 
      catch(Exception ex) 
      { 
       Console.WriteLine("Failed to enumerate directory: {0}", dir_info.FullName); 
       Console.WriteLine("Exception: {0}", ex.Message); 
      } 
     } 

ScanOptions是包含所有的掃描規則,包括大小規則結構。 正如您從代碼中可以看到的那樣,我當前遍歷所有規則以確定當前文件是否應該包含在文件列表中。這可以證明是致命的,因爲dSizeLimit字典中的條目數量不受限制,因爲用戶可以添加他想要的任何規則。

那麼有沒有更好的方法來處理這種查找?

P.S.請注意,我的目標框架應該是.NET 2.0,所以LINQ和其他非2.0友好的命名空間是不可能的。

long maxSize = long.MaxValue; 
foreach (KeyValuePair<string,long> entry in Opt.dSizeLimit) { 
    if(dir_info.FullName.StartsWith(entry.Key)) { 
     maxSize = Math.Min(maxSize, entry.Value); 
    } 
} 
// now iterate on the files, if no rules were present, file size 
// should always be < long.MaxValue 

沒有理由(如果我理解正確的)重新:

+1

子字符串是前綴,後綴還是任何子字符串? – leppie 2012-07-10 07:39:24

+0

@leppie子字符串是一個文件的根目錄,所以我們可以說它的前綴:) – 2012-07-10 07:55:10

+0

在這種情況下,它是超級簡單:)搜索一個C#實施。 – leppie 2012-07-10 07:57:14

回答

1

如果規則是一個目錄的基礎上應用,那麼你可以迭代上的文件,這樣的事情之前確定最嚴格的規則 - 每次對同一文件夾中的文件掃描規則,這樣可以節省很多操作。

爲了避免迭代字典,你可以使用只有一個值的選項結構,然後當你迭代文件夾時,你會用適當的值構造結構體,類似這樣的東西(僞代碼,只是爲了給你想法) :

foreach (DirectoryInfo subdir_info in dir_info.GetDirectories()) { 
    ScanOptions optForSubFolder = Opt; 
    if (/* more specific rules for given subfolder */) { 
     optForSubFolder.SizeLimit = /* value for subfolder */; 
    } 
    SearchDirectory(subdir_info, file_list, ref size, optForSubFolder); 
} 
+0

感謝您的回覆,我會認真考慮您的解決方案。我希望是否有辦法擺脫字典迭代,而不僅僅是減少它被調用的次數:) – 2012-07-10 07:59:54

+0

在審查你的解決方案後,似乎有一個小故障。如果沒有規則適用於掃描目錄,則maxSize將始終具有int.MaxValue。 – 2012-07-10 08:05:29

+0

@RedSerpent:取代int => long,所以Length <= long.MaxValue應該總是正常('FileInfo.Length'很長)。還添加了一個可能的想法來避免迭代,但它會需要在您的實現中進行一些更改,我猜... – 2012-07-10 09:02:25

相關問題