如何使用.NET快速获取目录中最旧的文件?

JL.*_*JL. 11 .net c# file-io

我有一个大约15-30万个文件的目录.我需要拉最老的一个.换句话说,首先创建的那个.有没有一种快速的方法来使用C#,除了将它们加载到一个集合然后排序?

Kir*_*rst 19

您必须将FileInfo对象加载到集合和排序中,但它是一个单行:

FileSystemInfo fileInfo = new DirectoryInfo(directoryPath).GetFileSystemInfos()
    .OrderBy(fi => fi.CreationTime).First();
Run Code Online (Sandbox Code Playgroud)

好的,两行是因为它是一个很长的陈述.

  • 如果您的目标只是返回单个项目,则切勿对集合进行排序。请改用 Aggregate()。有关示例,请参阅:http://stackoverflow.com/questions/10120944/c-sharp-finding-nearest-number-in-array/13896732#13896732 (2认同)
  • 很好的答案,但是,当然,`OrderByDescending` 首先返回最新的文件。要根据 OP 需要获取最旧的文件,只需更改为 `OrderBy`。此外,我更喜欢“FirstOrDefault”以避免异常,以防有一天目录可能为空。 (2认同)

Joh*_*ers 12

如果您控制目录(即,如果您的程序负责创建和维护该目录中的所有文件),那么您应该考虑单独跟踪每个文件的元数据; 也许在数据库中.

实际上,SQL Server 2008中的FileStream列类型可以帮助解决这个问题.您可以创建一个表,其中包含文件名,创建日期,修改日期和内容的FileStream列的列.您可以使用元数据列上的索引查找最旧的文件.您可以使用FileStream列找到内容.


bka*_*aid 7

简短的回答是否定的.Windows文件系统不按日期索引文件,因此没有本机方法可以执行此操作,更不用说.net方式而不枚举所有这些方法.


Kon*_*rin 5

你不能不排序就做,但你能做的就是让它快。

排序依据CreationTime可能很慢,因为首先访问每个文件的此属性涉及对文件系统的询问。

使用更快的目录枚举器,它可以在枚举时保留有关文件的更多信息,并允许更快地进行排序。

比较性能的代码:

static void Main(string[] args)
{
    var timer = Stopwatch.StartNew();

    var oldestFile = FastDirectoryEnumerator.EnumerateFiles(@"c:\windows\system32")
        .OrderBy(f => f.CreationTime).First();

    timer.Stop();

    Console.WriteLine(oldestFile);
    Console.WriteLine("FastDirectoryEnumerator - {0}ms", timer.ElapsedMilliseconds);
    Console.WriteLine();

    timer.Reset();
    timer.Start();

    var oldestFile2 = new DirectoryInfo(@"c:\windows\system32").GetFiles()
        .OrderBy(f => f.CreationTime).First();

    timer.Stop();

    Console.WriteLine(oldestFile2);
    Console.WriteLine("DirectoryInfo - {0}ms", timer.ElapsedMilliseconds);

    Console.WriteLine("Press ENTER to finish");
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

对我来说,它给出了这个:

VEN2232.OLB

FastDirectoryEnumerator - 27ms

VEN2232.OLB

目录信息 - 559 毫秒

  • @Konstantin:在 .NET 4.0 中,`DirectoryInfo.GetFiles()` 方法现在会保留附加信息,因此它不会受到您解决的性能问题的影响。 (3认同)