C#目录扫描性能

时间:2014-01-03 10:47:18

标签: c# io

我在网络驱动器上有一个文件夹结构

预订中心 - >设施 - >文件

例如

  • EUR / 12345678 / File_archive1.txt
  • EUR / 12345678 / File_archive2.txt
  • EUR / 12345678 / File_latest.txt
  • EUR / 5555 / File_archive1.txt
  • EUR / 5555 / File_archive2.txt
  • EUR / 5555 / File_latest.txt

当用户从下拉菜单中选择预订中心时,我希望代码查看该预订中心的上述网络路径,查看所有子文件夹并查找每个子文件夹中的最新文件,用它来填充第二个下拉列表的投资组合列表。但速度非常慢,我的代码如下。任何人都可以建议更快的方法吗?

public IDictionary<string, Portfolio> ReadPortfolios()
{
    var portfolios = new Dictionary<string, Portfolio>();

    var di = new DirectoryInfo(PortfolioPath);
    var possibleFacilities = di.GetDirectories();

    foreach (var possibleFacility in possibleFacilities)
    {
        try
        {
            if (possibleFacility.GetFiles().Any())
            {
                var mostRecentFile = possibleFacility.GetFiles().OrderBy(file => file.LastWriteTimeUtc).Last();

                var portfolio = UnzipAndReadPortfolio(mostRecentFile);
                if (portfolio == null) continue;

                portfolios.Add(possibleFacility.Name, portfolio);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(@"Failed to read portfolio: " + ex.Message);
        }
    }

    return portfolios;
}

3 个答案:

答案 0 :(得分:1)

如果您对“PortFolioPath”的所有子目录感兴趣,请尝试使用GetDirectories和/或GetFiles的重载,它允许您传递SearchOption.AllDirectories参数:它将避免多次访问网络。

你的循环中还有两个GetFiles()调用,你应该把第一个调用的结果存储在一个局部变量中。

你没有提供UnzipAndReadPortfolio的代码,这可能是最慢的部分(......或者不是?)。

请记住:在您的代码中,您通常可以认为“一种方法调用=一种网络访问”。因此,请尝试压扁循环,减少FSO访问等。

答案 1 :(得分:1)

可能实际上很小的性能提升

var mostRecentFile = possibleFacility.GetFiles()
                     .OrderBy(file => file.LastWriteTimeUtc)
                     .LastOrDefault();
if(mostRecentFile != null)
   ....

并注释掉第一个

// if(possibleFacility.GetFiles().Any())

答案 2 :(得分:1)

最明显的事情: 每次调用possibleFacility.GetFiles()时,都会获得该文件夹中的所有文件。 你必须调用它并将其保存在变量中然后使用这个变量。