Friday, September 28, 2007

Sorting Files by Name, Date, FileSize etc (C#)

It is simple to get a list of files in .NET, you simply do:

string folder = "c:\\windows\\";
string[] files = Directory.GetFiles(folder);

This will get all the files in C:\Windows (does not include subdirectories). However, they are sorted by name (A-Z) and there aren't any options in the GetFiles method to return them in any other order. Luckily, the results are returned as an array and they can be sorted with a custom comparer. I have created a FileComparer class that can be used to sort the files (works in both .NET 1.1 and 2.0):

public class FileComparer : IComparer
{
 public enum CompareBy
 {
  Name /* a-z */,
  LastWriteTime /* oldest to newest */,
  CreationTime  /* oldest to newest */,
  LastAccessTime /* oldest to newest */,
  FileSize /* smallest first */
 }
 // default comparison
 int _CompareBy = (int)CompareBy.Name;
 
 public FileComparer()
 {
 }
 
 public FileComparer(CompareBy compareBy)
 {
  _CompareBy = (int)compareBy;
 }
 
 int IComparer.Compare( object x, object y )
 {
  int output = 0;
  FileInfo file1 = new FileInfo(x.ToString());
  FileInfo file2 = new FileInfo(y.ToString());
  switch(_CompareBy)
  {
   case (int)CompareBy.LastWriteTime:
    output = DateTime.Compare(file1.LastWriteTime, file2.LastWriteTime);
    break;
   case (int)CompareBy.CreationTime:
    output = DateTime.Compare(file1.CreationTime, file2.CreationTime);
    break;
   case (int)CompareBy.LastAccessTime:
    output = DateTime.Compare(file1.LastAccessTime, file2.LastAccessTime);
    break;
   case (int)CompareBy.FileSize:
    output = Convert.ToInt32(file1.Length - file2.Length);
    break;
   case (int)CompareBy.Name:
   default:
    output = (new CaseInsensitiveComparer()).Compare( file1.Name, file2.Name );
    break;
  }
  return output;
 }
}

To use it is fairly simple:

string folder = "c:\\windows\\";
string[] files = Directory.GetFiles(folder);
IComparer comp = new FileComparer(FileComparer.CompareBy.FileSize);
Array.Sort(files, comp);
foreach(string file in files)
{
 Console.WriteLine(file);
}

This will output a list of files in the C:\Windows directory, sorted smallest to largest. If you want it the other way round, just call Array.Reverse(files) after the sort.

3 comments:

Yasser Azeem said...

great :)

Yasser

Mohammed El-Said said...

Thanks a lot for your post
it is really helpful and usable

Anonymous said...

Nice and clean. Thanks for the post.