Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
614 views
in Technique[技术] by (71.8m points)

c# - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...