【问题标题】:Removing files that are older than some number of days删除超过一定天数的文件
【发布时间】:2017-04-13 16:35:56
【问题描述】:

我想这在一个执行大量日志记录的应用程序中是一个很常见的要求。我正在开发一个 C# Windows 应用程序,.NET 3.5。

我的应用程序会生成大量日志文件,其中的文件名中包含当前日期,例如 20091112。删除超过 30 天的文件的最佳策略是什么。 我即将使用它的一种方法是遍历文件名,提取日期部分,转换为 DateTime 对象并与今天的日期进行比较。 有没有一个优雅的正则表达式解决方案:)?或者更好的东西?

【问题讨论】:

    标签: c#


    【解决方案1】:
    var files = new DirectoryInfo(@"c:\log").GetFiles("*.log");
    foreach (var file in files)
    {
        if (DateTime.UtcNow - file.CreationTimeUtc > TimeSpan.FromDays(30))
        {
            File.Delete(file.FullName);
        }
    }
    

    【讨论】:

    • 只是我必须获取内存中的所有 FileInfo 对象才能执行此操作。我正在考虑只获取名称,因为其中包含日期。这听起来合理吗?
    • 我想您可以与FindFirstFileFindNextFile API 互操作,或者查看.NET 4.0,您可以在其中使用DirectoryInfo.EnumerateFiles,它返回IEnumerable<FileInfo>
    • FileInfo 对象没有那么重——它们不是文件句柄或任何东西。例如,PowerShell 将它们用于流经管道的目录条目。
    • 如果我们要说比几个小时或几年大怎么办?有类似 TimeSpan.FromYears 或 TimeSpan.FromHours 的东西吗?如果有的话,为了简单起见,+1 也是一件容易的事
    • @BerkerYüceer,有TimeSpan.FromHours
    【解决方案2】:

    更新 .net 4.0:

    var files = new DirectoryInfo(directoryPath).GetFiles("*.log");
    foreach (var file in files.Where(file => DateTime.UtcNow - file.CreationTimeUtc > TimeSpan.FromHours(2))) {
         file.Delete();
    }
    

    【讨论】:

      【解决方案3】:
      string directoryPath = "/log"; // your log directory path
      
      foreach (string filePath in Directory.GetCreationTime(directoryPath))
      {
          TimeSpan fileAge = File.GetLastWriteTime(filePath) - DateTime.Now;
          if (fileAge.Days > 30)
          {
              File.Delete(filePath);
          }
      }
      

      【讨论】:

        【解决方案4】:

        据我了解,您希望使用文件名而不是修改时间。很好。

        那么代码是这样的:

            foreach (string file in Directory.GetFiles(path))
            {
                string fileNameOnly=Path.GetFileNameWithoutExtension(file);
                DateTime fileDate = DateTime.ParseExact(fileNameOnly, "yyyyMMDD", CultureInfo.CurrentCulture);
                if (DateTime.Now.Subtract(fileDate).TotalDays > MaxDays)
                    File.Delete(file);
            }
        

        【讨论】:

        • 这几乎就是我现在的代码中的内容。我只是有一个想法,我需要比较一组字符串中的日期模式,我也许可以使用正则表达式,但似乎我需要采用 foreach 循环方式。
        【解决方案5】:

        [在 PowerShell 中] 如果适合,您可以将以下内容粘贴到 PS1 文件中并使其成为管理脚本的一部分:-

        param($path=$(throw "需要指明路径"), $daysToRetain=$(throw "需要指明保留多少天"))

        目录 $path -r | ? { ([datetime]::UtcNow - $_.CreationTimeUtc).TotalDays -gt $daysToRetain } |删除

        编辑:如果您觉得使用文件时间不是正确的做法,您可以使用 -match 解析名称

        【讨论】:

          【解决方案6】:

          减去两个DateTime 对象会得到一个TimeSpan 对象,然后你可以检查它的TotalDays 属性。我想不出比这更简单的事情了。

          【讨论】:

            【解决方案7】:
            string[] files = Directory.GetFiles(path);
            foreach (string file in files)
             {
              if (File.GetLastWriteTime(file) < DateTime.Now.AddDays(-5))
                {
                  File.Delete(file);
                }
             }
            

            【讨论】:

            • 请考虑在您的答案中添加一些解释,而不仅仅是原始代码。您可能还想解释什么是您的答案添加到现有答案中。
            猜你喜欢
            • 2015-07-07
            • 2016-09-20
            • 2016-10-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-15
            • 2012-06-22
            相关资源
            最近更新 更多