6

私は現在ac#プログラムに取り組んでおり、ファイルの作成時刻を確認し、ファイルが2日より古い場合は削除します。これを達成するための次のコードスニペットがあります。

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

私のプログラムが実行されている間、それは常に新しいファイルを作成していて、別のスレッドがファイルがたとえば2日より古くないことをチェックします。PCの日付を4月24日に設定した場合、ファイルは期待どおりに作成および保持されます。その後、PCの日付を4月25日に変更すると、ファイルは2日以内であるため、そのまま残ると予想されますが、これはそれらは削除されているため、そうではありません。

ログの経過時間はに設定されているため、日付を4月26日に変更するまで、ファイルが削除されるとは思われませんでした。

私が間違っているのは、.NETを使用しているディレクトリ内の3か月以上前のStackoverflow Deleteファイルに関する別の質問を含む多くの例を見てきましたが、期待どおりに機能していません。

4

3 に答える 3

9

作成タイムスタンプの日付部分のみを考慮することを余儀なくされた場合、条件が満たされ、ファイルは(以前に)削除されます。とにかく、そのコードにいくつかの変更を加えることをお勧めします。

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);
            }
        }
    }
}

ノート

  • 私はまだ使用してDateTime.Nowいます。この種の操作では、正確な測定は必要ないと思います(そして、数日について話しているので、スレッドには数時間のスケジュールが設定されている可能性があります)。
  • アプリケーションで複数のログファイルを使用する場合は、それらすべてをパラメータとして指定でき、無視されます。
  • DeleteOldFiles0を指定して呼び出すとmaximumAgeInDays、使用されていないすべてのログファイルが遅延します(除外リストで指定されているとおり)。
  • ファイルが使用されている場合があります(これがあなたのケースではめったに起こらない場合でも)。このDeleteFileIfOlderThan関数は、少し遅れて削除を再試行します(Explorer.exe動作を模倣します)。

この関数は次のように呼び出すことができます。

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

もう少しメモ:

  • このコードはパスとファイル名を組み合わせていませんが、それを行う必要がある場合は、を使用する必要がありますPath.Combine()。パスが末尾の円記号で終わっているかどうかを確認するために、毎回車輪の再発明をしたくないと思います。
  • I / O操作が失敗する可能性があります!常に例外を確認してください。
于 2012-04-24T09:58:25.593 に答える
2

file.DeleteはFile.Delete(path)よりも意味があり、Path.Combine()はstring.Formatを使用するよりもはるかに意味があります。

私はこの答えに出くわしました、なぜ私がグーグルで何年も過ごした後にそれを前もって見つけなかったのか分かりません、しかしこれは問題を解決したようです。DateTime。日付が30日未満かどうかを確認する方法を比較しますか?。もう1つの問題は、ファイルの作成時間を使用していたことですが、私のシナリオでは、lastWriteTime.dateを使用する方が理にかなっています。

于 2012-04-24T10:16:17.223 に答える
0

私は追加の問題があるに違いないと思います

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

ファイルのタイプはFileSystemInfoですたぶん、 file.Nameを使用したいと思うでしょう。例:ディレクトリが「c:\」で、ファイルが「c:\ myfile.log」を指しているとすると、コードは「c:/ c:\myfile.log」を削除しようとします。これらの変数にあなたが何を持っているかを正確に推測するのは難しいです。

正しい交換は@HenkHoltermanによって提案されています:

file.Delete();
于 2012-04-24T10:16:15.703 に答える