C# 从目录和子目录中快速获取文件,按最新创建日期排序

C# 从目录和子目录中快速获取文件,按最新创建日期排序,c#,.net,C#,.net,我正在寻找一种方法,它将采用文件扩展名类型和目录,并返回此目录和子目录中按最新创建日期排序的所有文件,即首先返回最新文件 到目前为止,我已经确定了以下方法,这意味着要快速,但有没有更好的方法来做到这一点,我需要它返回FileInfo,而不是一个字符串,并按上述顺序排列 public static IEnumerable<string> GetFileList(string fileSearchPattern, string rootFolderPath) { Queue<str

我正在寻找一种方法,它将采用文件扩展名类型和目录,并返回此目录和子目录中按最新创建日期排序的所有文件,即首先返回最新文件

到目前为止,我已经确定了以下方法,这意味着要快速,但有没有更好的方法来做到这一点,我需要它返回FileInfo,而不是一个字符串,并按上述顺序排列

public static IEnumerable<string> GetFileList(string fileSearchPattern, string rootFolderPath)
{
Queue<string> pending = new Queue<string>();
pending.Enqueue(rootFolderPath);
string[] tmp;
while (pending.Count > 0)
{
    rootFolderPath = pending.Dequeue();
    tmp = Directory.GetFiles(rootFolderPath, fileSearchPattern);
    for (int i = 0; i < tmp.Length; i++)
    {
        yield return tmp[i];
    }
    tmp = Directory.GetDirectories(rootFolderPath);
    for (int i = 0; i < tmp.Length; i++)
    {
        pending.Enqueue(tmp[i]);
    }
}
}
public静态IEnumerable GetFileList(字符串fileSearchPattern,字符串rootFolderPath)
{
队列挂起=新队列();
pending.Enqueue(rootFolderPath);
字符串[]tmp;
而(挂起。计数>0)
{
rootFolderPath=pending.Dequeue();
tmp=Directory.GetFiles(rootFolderPath,fileSearchPattern);
对于(int i=0;i
当我研究这个问题空间时,我发现没有一种快速的方法来解决这个问题。原因是无论您采取何种方法,最终都必须转到操作系统以获取目录中的文件列表。文件系统也不像搜索引擎那样缓存/索引。因此,您最终需要自己重新爬网文件系统


但是,一旦获得原始信息,您就可以自己编制索引。

Directory.GetFiles确实有一个递归搜索的选项

虽然我还没有尝试过,但下面的方法应该可以奏效

    IEnumerable<FileInfo> GetFileList(string directory, string extension)
    {
        return Directory.GetFiles(directory, "*" + extension, SearchOption.AllDirectories)
            .Select(f => new FileInfo(f))
            .OrderByDescending(f => f.CreationTime);
    } 
IEnumerable GetFileList(字符串目录,字符串扩展名)
{
return Directory.GetFiles(目录“*”+扩展名,SearchOption.AllDirectories)
.选择(f=>newfileinfo(f))
.OrderByDescending(f=>f.CreationTime);
} 

以下内容适用于您的目的。您想使用Directory.EnumerateFiles(…)来允许文件列表提前使用更少的内存。当您请求下一个元素时,它将只查找下一个元素,而不是在开始时将整个集合加载到内存中

Directory.EnumerateFiles(rootFolderPath, fileSearchPattern, System.IO.SearchOption.AllDirectories).OrderBy(file => new FileInfo(file).CreationTime)

还有一个考虑。由于您在文件系统中执行的是相当盲目的搜索,如果您尝试枚举一个文件并引发异常,它将使枚举器无效,导致枚举器在未完成的情况下退出。我已经发布了该问题的解决方案

这可能是一个效率低下的解决方案,因为Directory.GetFiles()将等到加载完所有文件后再返回。你应该改为使用Directory.EnumerateFiles(…)。通常,我同意,但我们是按创建时间对文件排序的,所以我们可能必须先加载所有文件。为什么?文件创建时间不会改变,如果您有一个特别大的文件夹结构,那么将那么多字符串加载到内存中可能会出现内存不足错误。LINQ OrderBy方法在您请求下一个元素之前不会计算。啊:您已经将FileInfo创建放在OrderBy中了:这确实会节省内存空间。不幸的是,这个问题要求返回FileInfo,因此我的解决方案是:但是,如果将大文件结构作为FileInfo加载到内存中是一个问题,那么您的Matthew解决方案可以避免这个问题,但是您可能需要构造FileInfo两次。您仍然可以将.Select()放在其中,这一部分并不能节省你的记忆。使用Directory.EnumerateFiles(…)而不是Directory.GetFiles(…)可以节省大量内存。GetFiles(…)将在执行时立即为集合中的每个文件创建一个字符串实例。目录.EnumerateFiles(…)将只在您请求“下一个”文件时创建字符串实例。延迟加载在这方面有帮助吗?OP试图获取所有文件,因此延迟执行不会带来性能提升。延迟加载可能不是正确的措辞。使用EnumerateFiles(…)使用更小的内存占用,并且只在实际请求下一个元素时实际查找,返回速度更快。我已澄清我的回答,以表明这一点。