37

I am using such code to compare files to sort by date..

FileInfo f = new FileInfo(name1);
FileInfo f1 = new FileInfo(name2);
if (f.Exists && f1.Exists)
   output = DateTime.Compare(f.LastWriteTime, f1.LastWriteTime);

Is there any better and faster way to sort by Date?

At a time i can compare only 2 items...

I could not sort by getting all files from directory.

curiosity
  • 1,207
  • 5
  • 23
  • 34

8 Answers8

78

You can use LINQ:

var sortedFiles = new DirectoryInfo(@"D:\samples").GetFiles()
                                                  .OrderBy(f => f.LastWriteTime)
                                                  .ToList();
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 11
    oh snap, i love this solution! for the noobs, to have the latest files at the top, use `OrderByDescending` instead of `OrderBy` – davehale23 Jul 31 '12 at 16:43
  • AnyIdeas without using extension methods/LINQ because I'm targeting .NET 2.0 – Pratik Feb 27 '13 at 15:53
  • Thanks, this was very useful, my first time at LINQ! – mitchellt Feb 13 '14 at 16:36
  • 2
    `LastWriteTime` may return `{1/1/1601 3:30:00 AM}` if the file is not modified after initial creation! see [this](https://stackoverflow.com/a/23839158/2803565) – S.Serpooshan Dec 03 '17 at 12:26
13
    DirectoryInfo directoryInfo = new DirectoryInfo(@"D:\Temp");
    var result = directoryInfo.GetFiles("*.*",SearchOption.AllDirectories).OrderBy(t => t.LastWriteTime).ToList();
Alex Burtsev
  • 12,418
  • 8
  • 60
  • 87
  • `LastWriteTime` may return `{1/1/1601 3:30:00 AM}` if the file is not modified after initial creation! see [this](https://stackoverflow.com/a/23839158/2803565) – S.Serpooshan Dec 03 '17 at 12:25
10

What about using Array.Sort ?

string[] fileNames = Directory.GetFiles("directory ", "*.*");
DateTime[] creationTimes = new DateTime[fileNames.Length];
for (int i = 0; i < fileNames.Length; i++)
    creationTimes[i] = new FileInfo(fileNames[i]).CreationTime;
Array.Sort(creationTimes, fileNames);
eddie_cat
  • 2,527
  • 4
  • 25
  • 43
Vivek Goel
  • 22,942
  • 29
  • 114
  • 186
4

IMPORTANT - When ordering by LastWriteTime, it should be noted that if the file has never been modified, this date may return 1601 or 1600. Here is what MSDN says:

If the file described in the path parameter does not exist, this method returns 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time.

If your timezone is PST, like me the date will actually be 12/31/1600. To get around this and write more robust code you might consider something like this:

.OrderByDescending(f => f.LastWriteTime.Year <= 1601 ? f.CreationTime : f.LastWriteTime)
ProVega
  • 5,864
  • 2
  • 36
  • 34
4

This is another way of doing it for the whole directory:dateCompareFileInfo

if (Directory.Exists(DIRECTORY_NAME))
{
     DirectoryInfo di = new DirectoryInfo(DIRECTORY_NAME);
     FileInfo[] logFiles = di.GetFiles("AN-10-log.txt*");

     DateCompareFileInfo dateCompareFileInfo = new DateCompareFileInfo();

     Array.Sort(logFiles, dateCompareFileInfo);
}

And the you need a new DateCompareFileInfo class that implements IComparer:

class DateCompareFileInfo : IComparer<FileInfo>
{
    /// <summary>
    /// Compare the last dates of the File infos
    /// </summary>
    /// <param name="fi1">First FileInfo to check</param>
    /// <param name="fi2">Second FileInfo to check</param>
    /// <returns></returns>
    public int Compare(FileInfo fi1, FileInfo fi2)
    {
        int result;
        if (fi1.LastWriteTime == fi2.LastWriteTime)
        {
            result = 0;
        }
        else if (fi1.LastWriteTime < fi2.LastWriteTime)
        {
            result = 1;
        }
        else
        {
            result = -1;
        }

        return result;
    }
}
AidanO
  • 868
  • 1
  • 11
  • 33
0

This will convert the result to a readable class by the SSIS object:

var directory = Dts.Variables["User::SourceDir"].Value.ToString();
DirectoryInfo directoryInfo = new DirectoryInfo(directory);
var result = directoryInfo.GetFiles("*.xml", SearchOption.AllDirectories).OrderBy(t => t.LastWriteTime).ToList();
DataTable dsSorted = new DataTable();

DataColumn dc = new DataColumn("Value");
dsSorted.Columns.Add(dc);
foreach (FileInfo item in result)
{
    DataRow dr = dsSorted.NewRow();
    dr[0] = directory  + item ;
    dsSorted.Rows.Add(dr);
}

// lastModified = file.LastWriteTime;
Dts.Variables["User::FileNamesSorted"].Value = dsSorted;

// MessageBox.Show(Dts.Variables["User::FileNamesSorted"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
CDspace
  • 2,639
  • 18
  • 30
  • 36
PanLondon
  • 19
  • 2
0

Here is a solution I have found from MSDN Social.

DirectoryInfo di = new DirectoryInfo(@"c:\my-directory");
FileInfo[] files = di.GetFiles(@"*.*");
Array.Sort(files, (x, y) => Comparer<DateTime>.Default.Compare(x.LastWriteTime, y.LastWriteTime));
Tony
  • 1,827
  • 1
  • 22
  • 23
0
// Compare LastWriteTimeUtc of FileInfos
private class FileInfoDateComparer : IComparer<FileInfo> {
    //
    public long direction = 1;
    //
    public FileInfoDateComparer( bool ascending ) {
        direction = ascending ? 1 : -1;
    }
    //
    public int Compare( FileInfo fi1, FileInfo fi2 ) {
        long d = direction * ( fi1.LastWriteTimeUtc.Ticks - fi2.LastWriteTimeUtc.Ticks );
        return d < 0 ? -1 : d > 0 ? 1 : 0;
    }
}
//
//
private static FileInfo[] SortByDate( FileInfo[] afi, bool ascending ) {
    if ( null != afi ) {
        if ( 0 < afi.Length ) {
            var c = new FileInfoDateComparer( ascending );
            Array.Sort( afi, c );
        }
    }
    return afi;
}
cskwg
  • 790
  • 6
  • 13