从巨大的文件列表中选择前一天的文件

时间:2013-02-22 16:52:30

标签: c# .net winforms performance optimization

我从巨大的文件列表中选择前一天的文件

// selecting around 80-120 files from 20,000 - 25,000 

FileInfo[] files = (new DirectoryInfo(dirPath)).GetFiles("*.xml");
 string[] selectedFiles = (from c in files
                                          where c.CreationTime >= DateTime.Today.AddDays(-1) && c.CreationTime < DateTime.Today.AddHours(-2.0)
                                          select c.FullName).ToArray();

以上大约需要4-5分钟才能运行,请您告诉我如何优化它,而无需更改功能!

// file selection is between yesterday 0:00 to yesterday 22:00 <br >

如上面的代码所示。
好心劝告。

2 个答案:

答案 0 :(得分:1)

要尝试的东西:

FileInfo[] files = (new DirectoryInfo(dirPath)).GetFiles("*.xml");

DateTime lowDate = DateTime.Today.AddDays(-1);
DateTime highDate = DateTime.Today.AddHours(-2.0);

 string[] selectedFiles = (from c in files
                                          where c.CreationTime >= lowDate && c.CreationTime < highDate
                                          select c.FullName).ToArray();

这些日期可能会被计算20,000次以上。

答案 1 :(得分:0)

如果您只需要知道CreationTime,请不要为每个文件实例化一个新的FileInfo类。此外,您不必使用DirectoryInfo

我会用这样的东西:

DateTime lowDate = DateTime.Today.AddDays(-1);
DateTime highDate = DateTime.Today.AddHours(-2.0);

var filteredFileNames = new List<String>();
string[] fileNames;
fileNames = Directory.GetFiles(dirPath, "*.xml")

for (int i = 0; i < fileNames.Length; i++)
{
   var creationTime = File.GetCreationTimeUtc(fileNames[i]);
   if(creationTime >= lowDate && creationTime < highDate)
   {
    filteredFileNames.Add(filenNames[i]);
   }
}

如果您没有受到I / O限制,您仍然可以将时间范围的某些部分划分为不同的Tasks / Threads(取决于您所使用的.NET版本)并累积最后的名字。但是,完成的大部分工作都是Directory.GetFiles。特别是如果它是一个大目录。

当我不得不在一个目录中处理大量文件时,我继续使用Win 32 API的FindFirstFile / FindNextFileFindClose。它提供的开销更少,而且速度更快。

FindFirstFile Implementation