21

I am trying to get a list of all files in a folder from C#. Easy enough:

Directory.GetFiles(folder)

But I need the result sorted alphabetically-reversed, as they are all numbers and I need to know the highest number in the directory. Of course I could grab them into an array/list object and then do a sort, but I was wondering if there is some filter/parameter instead?

They are all named with leading zeros. Like:

00000000001.log
00000000002.log
00000000003.log
00000000004.log
..
00000463245.log
00000853221.log
00024323767.log

Whats the easiest way? I dont need to get the other files, just the "biggest/latest" number.

Sam
  • 7,252
  • 16
  • 46
  • 65
BerggreenDK
  • 4,915
  • 9
  • 39
  • 61

3 Answers3

37
var files = Directory.EnumerateFiles(folder)
                     .OrderByDescending(filename => filename);

(The EnumerateFiles method is new in .NET 4, you can still use GetFiles if you're using an earlier version)


EDIT: actually you don't need to sort the file names, if you use the MaxBy method defined in MoreLinq:

var lastFile = Directory.EnumerateFiles(folder).MaxBy(filename => filename);
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • 1
    And a ".ToList()" would be perfect :D – Matías Fidemraizer Aug 05 '11 at 13:03
  • 1
    @Matías Fidemraizer, why? It depends on what you intend to do with the results... – Thomas Levesque Aug 05 '11 at 13:06
  • Interesting with .NET4 (we run 3.5 I think), but same problem as @yas4891 I guess? every filename is pulled into memory before the LINQ syntax selects the correct item. I am looking for a simple parametre for the Directory object? is that possible? – BerggreenDK Aug 05 '11 at 13:07
  • @Thomas Because you know this works with deferred execution and since this is a sample and maybe question's author isn't a LINQ expert, it seems that this should avoid problems for him. – Matías Fidemraizer Aug 05 '11 at 13:10
  • @BerggreenDK Directory.GetFiles returns an array of strings (file names) so you're not iterating "files". – Matías Fidemraizer Aug 05 '11 at 13:13
  • 2
    @BerggreenDK, no, there is no parameter for Directory.GetFiles to specify the order. EnumerateFiles yields the file names lazily, so they're not all loaded in memory at once. However, the OrderBy will need to load everything before it can begin to sort... Instead you could use the MaxBy method defined in [MoreLinq](http://code.google.com/p/morelinq/). See my updated answer – Thomas Levesque Aug 05 '11 at 13:14
  • Okay thanks for great answers and comments everyone! Just had to get this confirmed. – BerggreenDK Apr 15 '13 at 10:27
16
var files = from file in Directory.GetFiles(folder)    
               orderby file descending 
               select file;

var biggest = files.First();

if you are really after the highest number and those logfiles are named like you suggested, how about:

Directory.GetFiles(folder).Length
yas4891
  • 4,774
  • 3
  • 34
  • 55
  • okay, this looks like LINQ syntax, as from what I understand it still pulls the whole directory into memory before selecting? I am searching for a "filter" on the Directory command itself, as we might have quite a load of files in same directory and this function will be called a lot. – BerggreenDK Aug 05 '11 at 13:06
  • Hmm. How about you clarify your post a bit more and tell us what you ultimately want to achieve? It seems like you are trying to "guess" the next valid integer in some naming scheme - right? – yas4891 Aug 05 '11 at 13:07
  • I want to know the name of the file with the highest number, either for appending more logs or to be able to produce the next number in line. So yes, "guessing the next" is one of the tasks. I dont need the list of all the others as my question also states. – BerggreenDK Aug 05 '11 at 13:10
  • 3
    If performance is really that big a matter (did you benchmark ?), you maybe should resolve to storing the highest number somewhere in memory (i.e. a class member / property) – yas4891 Aug 05 '11 at 13:15
  • Yes, that could be another option. But my question is just: IS THERE a parameter in .NET that does the filtering automatically or isnt it possible to get the reverse order of files. – BerggreenDK Aug 05 '11 at 14:18
  • I have tried it now, but got an error when the folder was empty. Guess its something with the First() command, so I used the Length to check if there is files at all before firing the LINQ – BerggreenDK Aug 08 '11 at 20:15
  • Yup! decided to listen to the community here. IF there is a performance issue, deal with it WHEN and IF it happens... ever! Buy a larger server/harddrive/controller. LOL! – BerggreenDK Aug 09 '11 at 12:23
6

Extending what @Thomas said, if you only need the top X files, you can do this:

int x = 10;
var files = Directory.EnumerateFiles(folder)
                 .OrderByDescending(filename => filename)
                 .Take(x);
Rick Liddle
  • 2,684
  • 19
  • 31
  • Thanks! That can be really helpful too. – BerggreenDK Feb 01 '17 at 22:48
  • i wanted to get each file from the folder/directory.my file name contains some ID _documentt_filename.docx , kind of .Now, i wanna split this file title with ID and store it in a table or in-memory. how to achieve this ? – samolpp2 Aug 29 '18 at 10:41
  • var dir = new DirectoryInfo(@"D:\folder1"); foreach (var singleFile in dir.EnumerateFiles("*.*", SearchOption.AllDirectories)) { if(singleFile != null && singleFile.Length > 0 ) { – samolpp2 Aug 29 '18 at 10:42