2012-07-10 95 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

相关问题