Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete files older than a date

I am currently working on a c# program where I check the creation time of a file and delete it if the file is older than 2 days. I have the following code snippet that should be achieving this.

DateTime creationTime = file.CreationTime.Date;
if (creationTime < DateTime.Now.AddDays(-logAge) && file.Name != currentLog)
{
    File.Delete(string.Format("{0}/{1}", directory, file));
}

While my program is running it is constantly creating new files and a separate thread checks that the files are no older than say 2 days. If I have my PC's date set to the 24th April the files are created and kept as expected, if I then change the PC's date to the 25th April I would expect the files to remain as they are not older than 2 days, however, this is not the case as they are being deleted.

Log age is set to so I wouldn't have expected files to be deleted until after I had changed the date to be the 26th April.

What am I doing wrong, I've looked at many examples including another question on Stackoverflow Delete files older than 3 months old in a directory using .NET but its not doing what I would expect it to.

like image 985
Boardy Avatar asked Apr 24 '12 09:04

Boardy


People also ask

How do I delete files older than a certain date in Linux?

-type f -newermt "YYYY-MM-DD HH:MM:SS" -delete . It saves you from having to pipe everything through xargs, and having to handle filesnames with spaces or other disruptive characters. For what it's worth, -newermt is a non-standard extension, though on Linux systems you will typically have GNU find .

How do I delete old Windows files?

In the search box on the taskbar, type settings, then choose it from the list of results. Select System > Storage > This PC and then scroll down the list and choose Temporary files. Under Remove temporary files, select the Previous version of Windows check box and then choose Remove files.

How do you automate delete files?

Setting a folder to auto-deletebutton for the folder and select Settings. From the Folder Settings screen scroll down to Automated Actions>Delete or Unshare. Check the Auto-delete this folder on a selected date checkbox and choose a date you want the folder to be deleted.


2 Answers

You forced to consider only the date part of the creation time-stamp then condition is satisfied and file will be deleted (earlier) anyway I suggest a few modifications to that code:

static class Helpers {
    public static void DeleteOldFiles(string folderPath, uint maximumAgeInDays,
                                      params string[] filesToExclude) {
        DateTime minimumDate = DateTime.Now.AddDays(-maximumAgeInDays);

        var filesToDelete = Directory.EnumerateFiles(folderPath)
            .Where(x => !IsExcluded(x, filesToExclude));

        foreach (var eligibleFileToDelete in filesToDelete)
            DeleteFileIfOlderThan(eligibleFileToDelete, minimumDate);
    }

    private const int RetriesOnError = 3;
    private const int DelayOnRetry = 1000;

    private static bool IsExcluded(string item, string[] exclusions) {
        return exclusions.Contains(item, StringComparer.CurrentCultureIgnoreCase);
    }

    private static void DeleteFileIfOlderThan(string path, DateTime date)
    {
        for (int i = 0; i < RetriesOnError; ++i) {
            try {
                var file = new FileInfo(path);
                if (file.CreationTime < date)
                    file.Delete();
            }
            catch (IOException) {
                System.Threading.Thread.Sleep(DelayOnRetry);
            }
            catch (UnauthorizedAccessException) {
                System.Threading.Thread.Sleep(DelayOnRetry);
            }
        }
    }
}

Notes

  • I'm still using DateTime.Now, I guess for this kind of operations you do not need any precision measurement (and you're talking about days so your thread may have a scheduled time of hours).
  • If your application uses multiple log files you can specify them all as parameters and they'll be ignored.
  • If you call DeleteOldFiles with 0 for maximumAgeInDays then you'll delay all log files not in use (as specified in the exclusion list).
  • Sometimes files can be in use (even if this should happen seldom in your case). The DeleteFileIfOlderThan function will retry to delete them after a short delay (it mimics Explorer.exe behavior).

You can call this function in this way:

Helpers.DeleteOldFiles(@"c:\mypath\", logAge, currentLog);

Few more notes:

  • This code doesn't combine path and file name but if you have to do it you should use Path.Combine(), I guess you do not want to reinvent the wheel each time to check if a path ends with a trailing backslash or not.
  • I/O operations can fail! Always check for exceptions.
like image 130
Adriano Repetti Avatar answered Oct 13 '22 00:10

Adriano Repetti


file.Delete does make more sense than File.Delete(path) and Path.Combine() makes a lot more sense than using string.Format.

I've stumbled across this answer, don't know why I didn't find it before hand after spending ages on google, but this appears to have fixed the problem. DateTime.Compare how to check if a date is less than 30 days old?. The other problem was that I was using the file creation time but for my scenario it made more sense to use lastWriteTime.date.

like image 29
Boardy Avatar answered Oct 12 '22 23:10

Boardy