在C#中对Directory.GetFiles的结果进行排序

53
我有以下代码可以列出一个目录中的所有文件。
class GetTypesProfiler
{
    static List<Data> Test()
    {
        List<Data> dataList = new List<Data>();
        string folder = @"DIRECTORY";
        Console.Write("------------------------------------------\n");
        var files = Directory.GetFiles(folder, "*.dll");
        Stopwatch sw;
        foreach (var file in files)
        {   
            string fileName = Path.GetFileName(file);
            var fileinfo = new FileInfo(file);
            long fileSize = fileinfo.Length;
            Console.WriteLine("{0}/{1}", fileName, fileSize);
        }
        return dataList;
    }
    static void Main()
    {
         ...
    }
}

我需要根据文件大小或按字母顺序打印文件信息。如何对Directory.GetFiles()的结果进行排序?


1
将您的数据添加到列表中,编写一个LINQ排序或自定义IComparer... - jv42
可能是 https://dev59.com/0XM_5IYBdhLWcg3w2XHw 的重复问题。 - Antonio Bakula
6个回答

100

使用LINQ非常容易。

要按名称排序,

var sorted = Directory.GetFiles(".").OrderBy(f => f);
为了按大小排序,
var sorted = Directory.GetFiles(".").OrderBy(f => new FileInfo(f).Length);

当您使用Directory.GetFile()检索文件时,您知道它们最初是如何排序的吗? - Bosak
@Bosak:很可能与文件系统的具体细节有关,就像“dir”命令给出一致但看起来随机的顺序一样。 - Jon
在我的电脑上,它按字母顺序列出文件和目录。我正在使用Windows 7。 - Pratik Singhal
你能解释一下这个 lambda 实际上在做什么吗?在我看来,它似乎是在返回自身,但这没有多少意义。 - kingfrito_5005
1
@kingfrito_5005,这些lambda函数只是将要排序的集合中的每个值映射到一个任意的排序值--这允许例如按其绝对值进行整数排序,使用i => Math.Abs(i)。但有许多情况下,我们有一组可比较的值,我们只想对其进行简单的排序,而没有任何花哨的投影。按值对整数进行排序?OrderBy(i => i)。按值对字符串进行排序?OrderBy(s => s)。在这种情况下,我们正在像这样对文件名(字符串)进行排序。 - Jon

15
按日期排序:(返回一个FileInfo枚举):

Directory.GetFiles(folder, "*.dll").Select(fn => new FileInfo(fn)).
                                    OrderBy(f => f.Length);

或者,按名称排序:

Directory.GetFiles(folder, "*.dll").Select(fn => new FileInfo(fn)).
                                    OrderBy(f => f.Name);
不必要创建 FileInfo 实例来按文件名排序,但如果您想即时应用不同的排序方法,最好先准备好 FileInfo 对象数组,然后只需通过 LengthName 属性对它们进行 OrderBy 排序,因此出现了这种实现。此外,看起来您无论如何都会创建 FileInfo,因此最好在任何情况下都有一个 FileInfo 对象集合。抱歉,第一次没有理解清楚,应该更仔细地阅读问题和文档。

GetFiles返回一个字符串数组,而不是FileInfo。 - Paul
2
这不是按文件长度排序,而是按文件名长度排序。 - Jon
这将根据文件名的长度进行排序,而不是文件本身的长度。 - George Duckett

7

如果您喜欢,可以在FileInfo对象上使用LINQ:

var orderedFiles =  Directory.GetFiles("").Select(f=> new FileInfo(f)).OrderBy(f=> f.CreationTime)

为了先获取最新的文件:var orderedFiles = Directory.GetFiles("").Select(f => new FileInfo(f)).OrderByDescending(f => f.CreationTime) - Jeff

0
// Getting Directory object
DirectoryInfo directoryInfo = new DirectoryInfo(folderName);

// getting files for this folder
FileInfo[] files = directoryInfo.GetFiles();

// Sorting using the generic Array.Sort function based on Names comparison
Array.Sort(files, delegate (FileInfo x, FileInfo y) { return String.Compare(x.Name, y.Name); });

// Sorting using the generic Array.Sort function based on the creation date of every folder
Array.Sort(files, delegate (FileInfo x, FileInfo y) { return DateTime.Compare(x.CreationTime, y.CreationTime); });

数组排序


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

你可以试试这个,对我有用。

[System.Runtime.InteropServices.DllImport("Shlwapi.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
private static extern int StrCmpLogicalW(string psz1, string psz2);
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] arrFi = di.GetFiles("*.*");
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return StrCmpLogicalW(x.Name, y.Name); });

0

如果您只需要按文件名排序,并且文件标题支持升序或降序逻辑顺序,那么这将起作用。我添加了变量以更好地控制源和搜索模式。

Using Dir = System.IO;

string Source = yourVariable;
string SearchPattern = yourVariable;

Dir.Directory.GetFiles(Source, SearchPattern, Dir.SearchOption.AllDirectories).OrderBy(s => s).ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接