【问题标题】:Delete files older than 3 months old in a directory using .NET使用 .NET 删除目录中超过 3 个月的文件
【发布时间】:2011-01-14 09:46:23
【问题描述】:

我想知道(使用 C#)我如何删除某个目录中超过 3 个月的文件,但我想日期时间段可能是灵活的。

请明确一点:我正在寻找超过 90 天的文件,换句话说,应该保留 90 天前创建的文件,删除所有其他文件。

【问题讨论】:

  • 如果文件量很大,最好使用 EnumerateFiles 和 EnumerateDirectories 而不是 GetFiles 和 GetDirectories,因为它们直接运行枚举而不是收集列表。但是,您必须使用 foreach 循环。

标签: c# .net file directory


【解决方案1】:

System.IO.File 类上的GetLastAccessTime 属性应该会有所帮助。

【讨论】:

    【解决方案2】:

    基本上,您可以使用 Directory.Getfiles(Path) 来获取所有文件的列表。之后,您遍历列表并按照 Keith 的建议调用 GetLastAccessTim()。

    【讨论】:

      【解决方案3】:

      你只需要FileInfo -> CreationTime

      而不仅仅是计算时间差。

      在 app.config 中,您可以保存 TimeSpan 值,该值表示文件必须被删除多长时间

      还可以查看DateTime Subtract 方法。

      祝你好运

      【讨论】:

        【解决方案4】:

        这里有一个sn-p,如何获取目录中文件的创建时间并找到3个月前(准确地说是90天前)创建的文件:

            DirectoryInfo source = new DirectoryInfo(sourceDirectoryPath);
        
            // Get info of each file into the directory
            foreach (FileInfo fi in source.GetFiles())
            {
                var creationTime = fi.CreationTime;
        
                if(creationTime < (DateTime.Now- new TimeSpan(90, 0, 0, 0)))
                {
                    fi.Delete();
                }
            }
        

        【讨论】:

        • 不需要ToList()DirectoryInfo.GetFiles() 返回一个FileInfo[]
        • 您应该在foreach() 循环之外声明一个新变量来保存(DateTime.Now- new TimeSpan(90, 0, 0, 0)) 的值。没有理由在循环中重复计算。
        【解决方案5】:

        或者,如果您需要根据创建日期删除文件,您可以使用File.GetCreationTime Method

        【讨论】:

          【解决方案6】:

          这样的事情不能做。

          using System.IO; 
          
          string[] files = Directory.GetFiles(dirName);
          
          foreach (string file in files)
          {
             FileInfo fi = new FileInfo(file);
             if (fi.LastAccessTime < DateTime.Now.AddMonths(-3))
                fi.Delete();
          }
          

          【讨论】:

          • 谢谢,我注意到您使用的是 lastAccessTime,这是创建时间吗?
          • 不,正如 propertyNames 所说:LastAccessTime - 如果你愿意,你应该去CreationTime 的财产!
          • 是的,您使用哪个属性完全取决于您。如果需要,您也可以使用 LastWriteTime。
          • +1 帮助我。您可以使用 File.GetCreationTime 或 File.GetLastAccessTime,而不是创建新的 FileInfo 实例。应该是一个小的性能改进。
          • 我猜 GetFiles 和 Delete 在您的环境中永远不会失败?只是指出这一点,因为这似乎是一个高度引用的答案。
          【解决方案7】:

          对于那些喜欢过度使用 LINQ 的人。

          (from f in new DirectoryInfo("C:/Temp").GetFiles()
           where f.CreationTime < DateTime.Now.Subtract(TimeSpan.FromDays(90))
           select f
          ).ToList()
              .ForEach(f => f.Delete());
          

          【讨论】:

          • var filesToDelete = new DirectoryInfo(@"C:\Temp").GetFiles().Where(x=>x.LastAccessTime
          • 哇!除了我之外,其他人认为过度使用 LINQ 很棒! ;)
          • .ToList() 调用除了通过匹配的文件进行第二次循环之外还添加了什么?
          • @Joel Mueller。 List&lt;T&gt; 定义了一个ForEach 方法,可用于将Action&lt;T&gt; 应用于所有元素。不幸的是,IEnumerable&lt;T&gt; 没有这样的扩展方法。
          • 好点。很久以前我为IEnumerable&lt;T&gt;写了自己的ForEach扩展方法,我有时会忘记它不是内置的。
          【解决方案8】:

          这是一个 1-liner lambda:

          Directory.GetFiles(dirName)
                   .Select(f => new FileInfo(f))
                   .Where(f => f.LastAccessTime < DateTime.Now.AddMonths(-3))
                   .ToList()
                   .ForEach(f => f.Delete());
          

          【讨论】:

          • @VladL 如果我删除 ToList(),我会得到一个“IEnumerable 不包含 ForEach”。我只是把它放在里面。
          • 我喜欢这个。但我会将删除包装在 try/catch 中
          • new DirectoryInfo(dir).GetFiles() 对于每个文件都比 new FileInfo(f) 快。
          【解决方案9】:

          类似的东西

                      foreach (FileInfo file in new DirectoryInfo("SomeFolder").GetFiles().Where(p => p.CreationTime < DateTime.Now.AddDays(-90)).ToArray())
                          File.Delete(file.FullName);
          

          【讨论】:

            【解决方案10】:
                        system.IO;
            
                         List<string> DeletePath = new List<string>();
                        DirectoryInfo info = new DirectoryInfo(Server.MapPath("~\\TempVideos"));
                        FileInfo[] files = info.GetFiles().OrderBy(p => p.CreationTime).ToArray();
                        foreach (FileInfo file in files)
                        {
                            DateTime CreationTime = file.CreationTime;
                            double days = (DateTime.Now - CreationTime).TotalDays;
                            if (days > 7)
                            {
                                string delFullPath = file.DirectoryName + "\\" + file.Name;
                                DeletePath.Add(delFullPath);
                            }
                        }
                        foreach (var f in DeletePath)
                        {
                            if (File.Exists(F))
                            {
                                File.Delete(F);
                            }
                        }
            

            用于页面加载或网络服务或任何其他用途。

            我的概念是 evrry 7 天我必须在不使用 DB 的情况下删除文件夹文件

            【讨论】:

              【解决方案11】:
                       //Store the number of days after which you want to delete the logs.
                       int Days = 30;
              
                        // Storing the path of the directory where the logs are stored.
                         String DirPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6) + "\\Log(s)\\";
              
                        //Fetching all the folders.
                          String[] objSubDirectory = Directory.GetDirectories(DirPath);
              
                          //For each folder fetching all the files and matching with date given 
                          foreach (String subdir in objSubDirectory)     
                          {
                              //Getting the path of the folder                 
                              String strpath = Path.GetFullPath(subdir);
                              //Fetching all the files from the folder.
                              String[] strFiles = Directory.GetFiles(strpath);
                              foreach (string files in strFiles)
                              {
                                  //For each file checking the creation date with the current date.
                                  FileInfo objFile = new FileInfo(files);
                                  if (objFile.CreationTime <= DateTime.Now.AddDays(-Days))
                                  {
                                      //Delete the file.
                                      objFile.Delete();
                                  }
                              }
              
                              //If folder contains no file then delete the folder also.
                              if (Directory.GetFiles(strpath).Length == 0)
                              {
                                  DirectoryInfo objSubDir = new DirectoryInfo(subdir);
                                  //Delete the folder.
                                  objSubDir.Delete();
                              }
              
                          }
              

              【讨论】:

                【解决方案12】:

                我试过这段代码,效果很好,希望得到回答

                namespace EraseJunkFiles
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                            DirectoryInfo yourRootDir = new DirectoryInfo(@"C:\yourdirectory\");
                            foreach (FileInfo file in yourRootDir.GetFiles())
                                if (file.LastWriteTime < DateTime.Now.AddDays(-90))
                                    file.Delete();
                        }
                    }
                }
                

                【讨论】:

                • 90 天 3 个月
                【解决方案13】:

                只需创建一个可以帮助您完成此任务的小删除功能,我已经测试了这段代码,它运行得很好。

                此功能会删除 90 天 之前的文件以及要从文件夹中删除的扩展名为 .zip 的文件。

                Private Sub DeleteZip()
                
                    Dim eachFileInMydirectory As New DirectoryInfo("D:\Test\")
                    Dim fileName As IO.FileInfo
                
                    Try
                        For Each fileName In eachFileInMydirectory.GetFiles
                            If fileName.Extension.Equals("*.zip") AndAlso (Now - fileName.CreationTime).Days > 90 Then
                                fileName.Delete()
                            End If
                        Next
                
                    Catch ex As Exception
                        WriteToLogFile("No Files older than 90 days exists be deleted " & ex.Message)
                    End Try
                End Sub
                

                【讨论】:

                  【解决方案14】:

                  例如: 要在源代码上运行我的文件夹项目,我需要创建两个文件夹。 我将这个算法设置为每周 2 天并分成 4 小时

                  public static void LimpiarArchivosViejos()
                      {
                          DayOfWeek today = DateTime.Today.DayOfWeek;
                          int hora = DateTime.Now.Hour;
                          if(today == DayOfWeek.Monday || today == DayOfWeek.Tuesday && hora < 12 && hora > 8)
                          {
                              CleanPdfOlds();
                              CleanExcelsOlds();
                          }
                  
                      }
                      private static void CleanPdfOlds(){
                          string[] files = Directory.GetFiles("../../Users/Maxi/Source/Repos/13-12-2017_config_pdfListados/ApplicaAccWeb/Uploads/Reports");
                          foreach (string file in files)
                          {
                              FileInfo fi = new FileInfo(file);
                              if (fi.CreationTime < DateTime.Now.AddDays(-7))
                                  fi.Delete();
                          }
                      }
                      private static void CleanExcelsOlds()
                      {
                          string[] files2 = Directory.GetFiles("../../Users/Maxi/Source/Repos/13-12-2017_config_pdfListados/ApplicaAccWeb/Uploads/Excels");
                          foreach (string file in files2)
                          {
                              FileInfo fi = new FileInfo(file);
                              if (fi.CreationTime < DateTime.Now.AddDays(-7))
                                  fi.Delete();
                          }
                      }
                  

                  【讨论】:

                    【解决方案15】:

                    我在作为服务运行的控制台应用程序中使用以下内容从 App.Settings 文件中获取目录信息。保留文件的天数也是可配置的,乘以 -1 可在 DateTime.Now 的 AddDays() 方法中使用。

                    static void CleanBackupFiles()
                            {
                                string gstrUncFolder = ConfigurationManager.AppSettings["DropFolderUNC"] + "";
                                int iDelAge = Convert.ToInt32(ConfigurationManager.AppSettings["NumDaysToKeepFiles"]) * -1;
                                string backupdir = string.Concat(@"\", "Backup", @"\");
                    
                                string[] files = Directory.GetFiles(string.Concat(gstrUncFolder, backupdir));
                    
                    
                                foreach (string file in files)
                                {
                                    FileInfo fi = new FileInfo(file);
                                    if (fi.CreationTime < DateTime.Now.AddDays(iDelAge))
                                    {
                                        fi.Delete();
                                    }
                                }
                    
                            }
                    

                    【讨论】:

                      【解决方案16】:

                      SSIS 类型的示例 ..(如果这对任何人都有帮助)

                                public void Main()
                                {
                                       // TODO: Add your code here
                              // Author: Allan F 10th May 2019
                      
                              //first part of process .. put any files of last Qtr (or older) in Archive area 
                              //e.g. if today is 10May2019 then last quarter is 1Jan2019 to 31March2019 .. any files earlier than 31March2019 will be archived
                      
                              //string SourceFileFolder = "\\\\adlsaasf11\\users$\\aford05\\Downloads\\stage\\";
                              string SourceFilesFolder = (string)Dts.Variables["SourceFilesFolder"].Value;
                              string ArchiveFolder = (string)Dts.Variables["ArchiveFolder"].Value;
                              string FilePattern = (string)Dts.Variables["FilePattern"].Value;
                              string[] files = Directory.GetFiles(SourceFilesFolder, FilePattern);
                      
                              //DateTime date = new DateTime(2019, 2, 15);//commented out line .. just for testing the dates .. 
                      
                              DateTime date = DateTime.Now;
                              int quarterNumber = (date.Month - 1) / 3 + 1;
                              DateTime firstDayOfQuarter = new DateTime(date.Year, (quarterNumber - 1) * 3 + 1, 1);
                              DateTime lastDayOfQuarter = firstDayOfQuarter.AddMonths(3).AddDays(-1);
                      
                              DateTime LastDayOfPriorQuarter = firstDayOfQuarter.AddDays(-1);
                              int PrevQuarterNumber = (LastDayOfPriorQuarter.Month - 1) / 3 + 1;
                              DateTime firstDayOfLastQuarter = new DateTime(LastDayOfPriorQuarter.Year, (PrevQuarterNumber - 1) * 3 + 1, 1);
                              DateTime lastDayOfLastQuarter = firstDayOfLastQuarter.AddMonths(3).AddDays(-1);
                      
                              //MessageBox.Show("debug pt2: firstDayOfQuarter" + firstDayOfQuarter.ToString("dd/MM/yyyy"));
                              //MessageBox.Show("debug pt2: firstDayOfLastQuarter" + firstDayOfLastQuarter.ToString("dd/MM/yyyy"));
                      
                      
                              foreach (string file in files)
                              {
                                  FileInfo fi = new FileInfo(file);
                      
                                  //MessageBox.Show("debug pt2:" + fi.Name + " " + fi.CreationTime.ToString("dd/MM/yyyy HH:mm") + " " + fi.LastAccessTime.ToString("dd/MM/yyyy HH:mm") + " " + fi.LastWriteTime.ToString("dd/MM/yyyy HH:mm"));
                                  if (fi.LastWriteTime < firstDayOfQuarter)
                                  {
                      
                                      try
                                      {
                      
                                          FileInfo fi2 = new FileInfo(ArchiveFolder);
                      
                                          //Ensure that the target does not exist.
                                          //fi2.Delete();
                      
                                          //Copy the file.
                                          fi.CopyTo(ArchiveFolder + fi.Name);
                                          //Console.WriteLine("{0} was copied to {1}.", path, ArchiveFolder);
                      
                                          //Delete the old location file.
                                          fi.Delete();
                                          //Console.WriteLine("{0} was successfully deleted.", ArchiveFolder);
                      
                                      }
                                      catch (Exception e)
                                      {
                                          //do nothing
                                          //Console.WriteLine("The process failed: {0}", e.ToString());
                                      }
                                  }
                              }
                      
                              //second part of process .. delete any files in Archive area dated earlier than last qtr ..
                              //e.g. if today is 10May2019 then last quarter is 1Jan2019 to 31March2019 .. any files earlier than 1Jan2019 will be deleted
                      
                              string[] archivefiles = Directory.GetFiles(ArchiveFolder, FilePattern);
                              foreach (string archivefile in archivefiles)
                              {
                                  FileInfo fi = new FileInfo(archivefile);
                                  if (fi.LastWriteTime < firstDayOfLastQuarter )
                                  {
                                      try
                                      {
                                          fi.Delete();
                                      }
                                      catch (Exception e)
                                      {
                                          //do nothing
                                      }
                                  }
                              }
                      
                      
                                       Dts.TaskResult = (int)ScriptResults.Success;
                                }
                      

                      【讨论】:

                        【解决方案17】:

                        由于new FileInfo(filePath) 的解决方案不易测试,我建议像DirectoryFilePath 这样的类使用包装器:

                        public interface IDirectory
                        {
                            string[] GetFiles(string path);
                        }
                        
                        public sealed class DirectoryWrapper : IDirectory
                        {
                            public string[] GetFiles(string path) => Directory.GetFiles(path);
                        }
                        
                        public interface IFile
                        {
                            void Delete(string path);
                            DateTime GetLastAccessTime(string path);
                        }
                        
                        public sealed class FileWrapper : IFile
                        {
                            public void Delete(string path) => File.Delete(path);
                            public DateTime GetLastAccessTimeUtc(string path) => File.GetLastAccessTimeUtc(path);
                        }
                        
                        

                        然后使用这样的东西:

                        public sealed class FooBar
                        {
                            public FooBar(IFile file, IDirectory directory)
                            {
                                File = file;
                                Directory = directory;
                            }
                        
                            private IFile File { get; }
                            private IDirectory Directory { get; }
                        
                            public void DeleteFilesBeforeTimestamp(string path, DateTime timestamp)
                            {
                                if(!Directory.Exists(path))
                                    throw new DirectoryNotFoundException($"The path {path} was not found.");
                        
                                var files = Directory
                                    .GetFiles(path)
                                    .Select(p => new
                                    {
                                        Path = p,
                                        // or File.GetLastWriteTime() or File.GetCreationTime() as needed
                                        LastAccessTimeUtc = File.GetLastAccessTimeUtc(p) 
                                    })
                                    .Where(p => p.LastAccessTimeUtc < timestamp);
                        
                                foreach(var file in files)
                                {
                                    File.Delete(file.Path);
                                }
                            }
                        }
                        

                        【讨论】:

                          【解决方案18】:

                          当想要在一定时间内删除文件时,最规范的方法是使用文件的 LastWriteTime(上次修改文件的时间):

                          Directory.GetFiles(dirName)
                                   .Select(f => new FileInfo(f))
                                   .Where(f => f.LastWriteTime < DateTime.Now.AddMonths(-3))
                                   .ToList()
                                   .ForEach(f => f.Delete());
                          

                          (以上基于 Uri 的回答,但使用LastWriteTime。)

                          每当您听到人们谈论删除超过某个时间范围的文件(这是一种非常常见的活动)时,根据文件的 LastModifiedTime 执行此操作几乎总是他们想要的。

                          或者,对于非常不寻常的情况,您可以使用以下内容,但请谨慎使用,因为它们带有警告。

                          CreationTime
                          .Where(f => f.CreationTime < DateTime.Now.AddMonths(-3))
                          

                          文件在当前位置创建的时间。但是,如果文件已被复制,请注意,这将是它被复制的时间,CreationTime 将比文件的LastWriteTime更新

                          LastAccessTime
                          .Where(f => f.LastAccessTime < DateTime.Now.AddMonths(-3))
                          

                          如果您想根据上次读取文件的时间删除文件,您可以使用它,但不能保证它会被更新,因为它可以在 NTFS 中禁用。检查fsutil behavior query DisableLastAccess 以查看它是否已打开。同样在 NTFS 下,文件的 LastAccessTime 在被访问后可能需要长达一个小时才能更新。

                          【讨论】:

                            猜你喜欢
                            • 2018-01-31
                            • 1970-01-01
                            • 2020-01-29
                            • 2015-06-02
                            • 2012-04-25
                            • 1970-01-01
                            • 2022-10-07
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多