Удалите файлы старше 3 месяцев в каталоге с помощью.NET
Я хотел бы знать (используя C#), как я могу удалить файлы в определенном каталоге старше 3 месяцев, но я думаю, что период дат может быть гибким.
Просто для ясности: я ищу файлы, которые старше 90 дней, другими словами, файлы, созданные менее 90 дней назад, должны быть сохранены, все остальные удалены.
15 ответов
Что-то вроде этого не так.
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();
}
Вот лямбда с 1 вкладышем:
Directory.GetFiles(dirName)
.Select(f => new FileInfo(f))
.Where(f => f.LastAccessTime < DateTime.Now.AddMonths(-3))
.ToList()
.ForEach(f => f.Delete());
Для тех, кто любит чрезмерно использовать 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());
Вот фрагмент того, как получить время создания файлов в каталоге и найти те, которые были созданы 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();
}
}
Самый канонический подход, когда вы хотите удалить файлы в течение определенного времени, - использовать LastWriteTime файла (последний раз, когда файл был изменен):
Directory.GetFiles(dirName)
.Select(f => new FileInfo(f))
.Where(f => f.LastWriteTime < DateTime.Now.AddMonths(-3))
.ToList()
.ForEach(f => f.Delete());
(Вышеуказанное основано на ответе Ури, но с 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 файла после обращения к нему может потребоваться до часа.
Должно помочь свойство GetLastAccessTime класса System.IO.File.
Я попробовал этот код, и он работает очень хорошо, надеюсь, что это ответ
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();
}
}
}
Что-то вроде того
foreach (FileInfo file in new DirectoryInfo("SomeFolder").GetFiles().Where(p => p.CreationTime < DateTime.Now.AddDays(-90)).ToArray())
File.Delete(file.FullName);
В основном вы можете использовать Directory.Getfiles(Path), чтобы получить список всех файлов. После этого вы перебираете список и вызываете GetLastAccessTim(), как предложил Кейт.
Например: чтобы перейти к проекту "Моя папка с исходным кодом", мне нужно создать две папки. Я делаю этот алгоритм до 2 дней в неделю и в четыре часа
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();
}
}
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 день, я должен удалить файл папки без использования БД
Пример типа 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;
}
Поскольку решения с 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);
}
}
}
Я использую следующее в консольном приложении, работающем в качестве службы, чтобы получить информацию о каталоге из файла App.Settings. Количество дней хранения файлов также настраивается, умножается на -1 для использования в методе AddDays() DateTime.Now.
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();
}
}
}
//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();
}
}
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
Вам просто нужно FileInfo -> CreationTime
и чем просто рассчитать разницу во времени.
в app.config вы можете сохранить значение TimeSpan того, сколько лет должен быть удален файл
также проверьте метод вычитания DateTime.
удачи
Кроме того, вы можете использовать метод File.GetCreationTime, если вам нужно удалить файлы на основе дат создания.