How to delete files based on timestamp embedded in file name

56 Views Asked by At

I am filtering files to delete based on creation timestamp. The piece of code that uses file creation works fine except that these files have embedded timestamp that somehow is different from create time. This causes a bunch of files to be missed for deletion.

This is what I am currently using:

public static void DeleteLogFiles(string sPath, DateTime dtDate, int iLogFileRetention)
{
    try
    {
        (from f in new DirectoryInfo(sPath).GetFiles()
            where f.CreationTime < dtDate.Subtract(TimeSpan.FromDays(iLogFileRetention))
            select f
            ).ToList()
            .ForEach(f => f.Delete());
    }
    catch (Exception ex)
    {
    }
}

Timestamp embeddd in file name is formatted as MMddyyyyHHmmss.

ABCD_20240309000024.dat, but its last modified date is 03/12/2024

How do I modify the Linq statement above to use embedded timestamp rather than create/modified date?

where f.FileName ?????
2

There are 2 best solutions below

1
Mustafa Özçetin On BEST ANSWER

Use the following helper method

static DateTime GetDateTime(string strTimestamp)
{
    // ABCD_20240309000024.dat
    string fileName = Path.GetFileNameWithoutExtension(strTimestamp);
    string[] parts = fileName.Split("_");
    string dateTimePart = parts[1];
    DateTime dateTime = DateTime.ParseExact(dateTimePart, "yyyyMMddFFFFFF", CultureInfo.InvariantCulture);
    return dateTime;
}

and change the Linq as follows:

(from f in new DirectoryInfo(sPath).GetFiles()
    where (f.CreationTime < dtDate.Subtract(TimeSpan.FromDays(iLogFileRetention))
    || GetDateTime(f.Name) < dtDate.Subtract(TimeSpan.FromDays(iLogFileRetention)))
    select f
    ).ToList()
    .ForEach(f => f.Delete());

Please note that I used the date time format yyyyMMdd and you might need to change this.

0
jmcilhinney On

This is untested but I think it should do the job:

var filePaths = from filePath in Directory.GetFiles(folderPath)
                where DateTime.TryParseExact(Path.GetFileNameWithoutExtension(filePath).Split('_').Last(),
                                             "MMddyyyyHHmmss",
                                             null,
                                             DateTimeStyles.None,
                                             out var creationTime) &&
                      creationTime < thresholdDate
                select filePath;

That thresholdDate is something that you should be calculating once, before the query, not within the query. Anything that you know will be the same for every input item should not be calculated within the query.