使用 .NET 删除目录中超过 3 个月的文件
Posted
技术标签:
【中文标题】使用 .NET 删除目录中超过 3 个月的文件【英文标题】:Delete files older than 3 months old in a directory using .NET 【发布时间】:2011-01-14 09:46:23 【问题描述】:我想知道(使用 C#)我如何删除某个目录中超过 3 个月的文件,但我想日期时间段可能是灵活的。
请明确一点:我正在寻找超过 90 天的文件,换句话说,应该保留 90 天前创建的文件,删除所有其他文件。
【问题讨论】:
如果文件量很大,最好使用 EnumerateFiles 和 EnumerateDirectories 而不是 GetFiles 和 GetDirectories,因为它们直接运行枚举而不是收集列表。但是,您必须使用 foreach 循环。 【参考方案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<T>
定义了一个ForEach
方法,可用于将Action<T>
应用于所有元素。不幸的是,IEnumerable<T>
没有这样的扩展方法。
好点。很久以前我为IEnumerable<T>
写了自己的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(),我会得到一个“IEnumerablenew 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)
的解决方案不易测试,我建议像Directory
、File
和Path
这样的类使用包装器:
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 在被访问后可能需要长达一个小时才能更新。
【讨论】:
以上是关于使用 .NET 删除目录中超过 3 个月的文件的主要内容,如果未能解决你的问题,请参考以下文章