Remove older file(s) from list based on create date

Viewed 107

I have a set of folders containing log files. Each folder is named as the date the log files were created. I am getting the content of these folders within X days of today and storing the resulting FileInfo in a list. So it is possible to have file info with same file name X times, or less.

I need to keep only the latest files based on create date. So, if the list contains multiple entries where fi.FileName is the same, I need to keep the latest, based on fi.CreateDate and ditch the other instance(s).

I tried something like this but am messing up somewhere:

files = files.GroupBy(i => new {i.FileName, i.CreateDate}).Select(i => i.Last()).ToList();
2 Answers

You can use such a method to get files to purge:

using System.IO;
using System.Linq;
using System.Collections.Generic;

static public IEnumerable<FileInfo> GetTraceFiles(bool sortByDateOnly = true)
{
  string folder = "MyFullPath";   // Can be from some instance
  string prefix = "MyTraceFile-"; // global vars
  string extension = ".log";      // and config
  var list = Directory.GetFiles(folder, prefix + "*" + extension)
                      .Where(f => !IsFileLocked(f))
                      .Select(f => new FileInfo(f))
                      .OrderBy(fi => fi.CreationTime);
  return sortByDateOnly ? list : list.ThenBy(fi => fi.FullName);
}

And this clear method:

static public void ClearTraces(int retain = 0)
{
  var list = GetTraceFiles();
  if ( retain > 0 ) list = list.Take(list.Count() - retain + 1);
  foreach ( var fileInfo in list )
    try 
    { 
      File.Delete(fileInfo.FullName); 
    } 
    catch 
    { 
    }
}

Here it retains retain last files but you can adapt to add a Where clause to use a date before which to erase:

.Where(fi => fi.CreationTime < ...);

Also instead of using the file system creation date and time, it is possible to use the file pattern in case for example MyTrace-YYYY-MM-DD@HH-MM-SS...

IsFileLocked comes from:

Is there a way to check if a file is in use?

You must change your sort code as follows:

  files = files.OrderBy(f=>f.CreateDate).GroupBy(i => i.FileName).Select(i => i.Last()).ToList();

This one also will give the same result:

 files =files.GroupBy(i => i.FileName).Select(i => i.OrderByDescending(f=>f.CreateDate).First()).ToList();
Related