Sorting the result of Directory.GetFiles in C#
Asked Answered
A

6

53

I have this code to list all the files in a directory.

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()
    {
         ...
    }
}

I need to print out the file info based on file size or alphabetical order. How can I sort the result from Directory.GetFiles()?

Apps answered 9/6, 2011 at 14:17 Comment(2)
Add your data to the list, write a LINQ sorting or a custom IComparer...Fimbria
possible duplicate of #1199506Sunken
K
102

Very easy with LINQ.

To sort by name,

var sorted = Directory.GetFiles(".").OrderBy(f => f);

To sort by size,

var sorted = Directory.GetFiles(".").OrderBy(f => new FileInfo(f).Length);
Klemperer answered 9/6, 2011 at 14:21 Comment(5)
do you know how are the files sorted in the first place when you retrieve them with Directory.GetFile() ?Micaelamicah
@Bosak: Most likely some order that has to do with the specifics of the filesystem, much like dir gives you a consistent but random-looking order.Klemperer
On my computer, It gives the files and the directories in alphabetical order. I am using Windows 7Adest
Can you explain what that lambda is actually doing? It looks to me as if its returning itself, but that makes little sense.Tonjatonjes
@Tonjatonjes those lambdas simply map each value in the collection to be sorted to an arbitrary sort value -- this allows e.g. to sort integers by their absolute value with i => Math.Abs(i). But there are many cases where we have a collection of comparable values and we just want to sort it without any fancy projections. Sort integers by value? OrderBy(i => i). Sort strings by value? OrderBy(s => s). In this instance we are sorting filenames (strings) exactly like that.Klemperer
L
15

To order by date: (returns an enumerable of FileInfo):

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

or, to order by name:

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

Making FileInfo instances isn't necessary for ordering by file name, but if you want to apply different sorting methods on the fly it's better to have your array of FileInfo objects in place and then just OrderBy them by Length or Name property, hence this implementation. Also, it looks like you are going to create FileInfo anyway, so it's better to have a collection of FileInfo objects either case.

Sorry I didn't get it right the first time, should've read the question and the docs more carefully.

Lifeguard answered 9/6, 2011 at 14:20 Comment(3)
GetFiles returns a string array, not fileinfo.Coenurus
This doesn't sort by file length, it sorts by filename length.Klemperer
That will sort on length of filenames, not length of files themselves.Freak
C
7

You can use LINQ if you like, on a FileInfo object:

var orderedFiles =  Directory.GetFiles("").Select(f=> new FileInfo(f)).OrderBy(f=> f.CreationTime)
Coenurus answered 9/6, 2011 at 14:21 Comment(1)
To get newest files first: var orderedFiles = Directory.GetFiles("").Select(f=> new FileInfo(f)).OrderByDescending(f=> f.CreationTime)Analemma
D
0

try this, it works for me

[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); });
Deplore answered 13/5, 2019 at 13:24 Comment(0)
S
0

This works if you only need to sort by file name and the file title supports the ascending or descending logical order.I add variables to have a bit more control of the source and search pattern.

Using Dir = System.IO;

string Source = yourVariable;
string SearchPattern = yourVariable;

Dir.Directory.GetFiles(Source, SearchPattern, Dir.SearchOption.AllDirectories).OrderBy(s => s).ToList();
Secrecy answered 19/11, 2019 at 15:14 Comment(0)
I
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); });

Array Sort

Indocile answered 4/5, 2022 at 2:6 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Vandervelde

© 2022 - 2024 — McMap. All rights reserved.