Supprimer des fichiers plus anciens qu'une date

je travaille actuellement sur un programme c# où je vérifie le temps de création d'un fichier et le supprime si le fichier est plus ancien que 2 jours. J'ai l'extrait de code suivant qui devrait être atteint.

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

pendant que mon programme tourne, il crée constamment de nouveaux fichiers et un thread séparé vérifie que les fichiers ne sont pas plus vieux que par exemple 2 jours. Si j'ai la date de mon PC fixée au 24 Avril les fichiers sont créés et conservés comme prévu, si je puis changer la date du PC au 25 avril je m'attendrais à ce que les fichiers restent car ils ne sont pas plus de 2 jours, mais ce n'est pas le cas car ils sont supprimés.

L'âge de Log est défini de sorte que je ne m'attendais pas à ce que les fichiers soient supprimés avant d'avoir changé la date pour être le 26 avril.

Qu'est-ce que je fais de mal, j'ai regardé de nombreux exemples, y compris une autre question sur Stackoverflow supprimer les fichiers de plus de 3 mois dans un répertoire utiliser .NET mais il ne fait pas ce que je m'attendrais à ce qu'il fasse.

4
demandé sur Community 2012-04-24 13:52:26

3 réponses

vous avez été forcé de considérer seulement la partie date de l'horodatage de création puis la condition est satisfaite et le fichier sera supprimé (plus tôt) de toute façon je suggère quelques modifications à ce 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

  • j'utilise toujours DateTime.Now , je suppose que pour ce genre d'opérations vous n'avez pas besoin de mesure de précision (et vous parlez de jours afin que votre fil peut avoir un horaire programmé de heures ).
  • Si votre application utilise plusieurs fichiers journaux vous pouvez spécifier tous les paramètres, ils seront ignorés.
  • si vous appelez DeleteOldFiles avec 0 pour maximumAgeInDays alors vous retarderez tous les fichiers journaux non utilisés (comme spécifié dans la liste d'exclusion).
  • parfois des fichiers peuvent être utilisés (même si cela devrait se produire rarement dans votre cas). La fonction DeleteFileIfOlderThan essaiera de les supprimer après un court délai (il imite le comportement Explorer.exe ).

vous pouvez appeler cette fonction de cette façon:

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

quelques autres notes:

  • ce code ne combine pas chemin et nom de fichier mais si vous devez le faire , vous devez utiliser Path.Combine() , je suppose que vous ne voulez pas réinventer la roue à chaque fois pour vérifier si un chemin se termine avec un antislash arrière ou non.
  • les opérations d'E / S peuvent échouer! Vérifiez toujours les exceptions.
7
répondu Adriano Repetti 2016-09-06 10:16:12
"151900920 de fichier".Supprimer fait plus de sens que le fichier.Supprimer(chemin d'accès) et le Chemin d'accès.Combinez () fait beaucoup plus de sens que d'utiliser string.Format.

j'ai trébuché sur cette réponse, Je ne sais pas pourquoi je ne l'ai pas trouvé avant hand après avoir passé des années sur google, mais cela semble avoir corrigé le problème. DateTime.Comparer comment vérifier si une date a moins de 30 jours? . L'autre problème était que j'utilisais le temps de création du fichier mais pour mon scénario il ça avait plus de sens d'utiliser la dernière fois.date.

1
répondu Boardy 2017-05-23 12:10:19

je suppose qu'un problème supplémentaire doit être dans

File.Delete(string.Format("{0}/{1}", directory, file));

votre fichier est de type FileSystemInfo . Vous vouliez peut-être utiliser le fichier .Nom . Exemple: disons que répertoire est "c:\" et fichier points "c:\myfile.log" , votre code essaiera de supprimer " c:/c:\myfile.log ". J'ai du mal à deviner ce que vous avez dans ces variables.

le remplacement Correct est suggéré par @HenkHolterman:

file.Delete();
0
répondu jing 2012-04-24 10:16:15