.NET을 사용하여 디렉토리에서 3 개월 이상 된 파일 삭제


117

3 개월 이상 된 특정 디렉터리의 파일을 삭제하는 방법을 알고 싶습니다 (C # 사용).하지만 날짜 기간이 유연 할 수 있다고 생각합니다.

명확하게 말하면, 90 일보다 오래된 파일을 찾고 있습니다. 즉, 90 일 이내에 생성 된 파일은 보관해야하고 다른 파일은 모두 삭제해야합니다.


파일의 양이 많은 경우 목록을 수집하는 대신 열거를 직접 실행하기 때문에 GetFiles 및 GetDirectories 대신 EnumerateFiles 및 EnumerateDirectories를 사용하는 것이 가장 좋습니다. 그러나 foreach 루프를 사용해야합니다.
Larry

답변:


257

이런 식으로 할 수 있습니다.

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을 사용하는 것으로 나타났습니다. 지금이 생성 시간입니까?
JL.

10
아니, propertyNames가 말했듯이 : LastAccessTime-원한다면 재산에 가야 CreationTime합니다!
Andreas Niedermair

4
예, 사용하는 속성은 전적으로 귀하에게 달려 있습니다. 원하는 경우 LastWriteTime을 사용할 수도 있습니다.
Steve Danner

3
나를 도와 준 +1. 새 FileInfo 인스턴스를 만드는 대신 File.GetCreationTime 또는 File.GetLastAccessTime을 사용할 수 있습니다. 약간의 성능 향상이어야합니다.
Mario The Spoon

5
귀하의 환경에서 GetFiles 및 Delete가 실패하지 않는 것 같습니다. 이것은 매우 참조 된 답변 인 것처럼 보이기 때문에 지적합니다.
Andrew Hagner 2013-06-28

93

다음은 1 줄짜리 람다입니다.

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

@VladL ToList ()를 삭제하면 "IEnumerable <FileInfo> does not contain ForEach"가 표시됩니다. 그냥 보관했습니다.
James Love

3
나는 이것을 좋아한다. 하지만 try / catch에서 삭제를 래핑합니다
H20rider

new DirectoryInfo(dir).GetFiles()new FileInfo(f)모든 단일 파일 보다 빠릅니다 .
Vojtěch Dohnal

29

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

1
var filesToDelete = new DirectoryInfo (@ "C : \ Temp"). GetFiles (). Where (x => x.LastAccessTime <DateTime.Now.AddMonths (-3)); // variation
Ta01 2010

2
와우! 나 외에 다른 사람은 LINQ를 과도하게 사용하는 것이 굉장하다고 생각합니다! ;)
Filip Ekberg

.ToList()호출은 일치하는 파일을 통해 두 번째 루프 외에 무엇을 추가합니까?
Joel Mueller

2
@Joel Mueller. 모든 요소 에을 적용하는 데 사용할 수 List<T>있는 ForEach메서드를 정의합니다 Action<T>. 불행히도 IEnumerable<T>.
Samuel Neff

1
좋은 지적. 나는 아주 오래 전에 내 자신의 ForEach확장 방법을 썼다. IEnumerable<T>때때로 그것이 내장되어 있지 않다는 것을 잊는다.
Joel Mueller

14

다음은 디렉토리에서 파일 생성 시간을 가져오고 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[].
Dynami Le Savard

4
foreach()의 값을 유지하려면 루프 외부에서 새 변수를 선언해야합니다 (DateTime.Now- new TimeSpan(90, 0, 0, 0)). 루프에서 반복적으로 계산할 이유가 없습니다.
Chad


1

기본적으로 Directory.Getfiles (Path)를 사용하여 모든 파일 목록을 가져올 수 있습니다. 그 후 목록을 반복하고 Keith가 제안한대로 GetLastAccessTim ()을 호출합니다.


1

그런 것

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

1

이 코드를 사용해 보았고 매우 잘 작동합니다.

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

2
90 일 <> 3 개월
Daniel

1

특정 기간 동안 파일을 삭제하려는 경우 가장 일반적인 방법은 파일의 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이 업데이트되는 데 최대 1 시간이 걸릴 수 있습니다.


0

FileInfo- > CreationTime 만 필요합니다.

시차를 계산하는 것보다

app.config 에서 파일을 삭제해야하는 기간 의 TimeSpan 값을 저장할 수 있습니다.

DateTime Subtract 메서드 도 확인하십시오 .

행운을 빕니다



0
            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를 사용하지 않고 폴더 파일을 삭제해야합니다.


0
         //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();
                }

            }

0

예 : 소스에서 내 폴더 프로젝트로 이동하려면 두 개의 폴더가 필요합니다. 이 알고 림을 주 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();
        }
    }

0

App.Settings 파일에서 디렉터리 정보를 가져 오기 위해 서비스로 실행되는 콘솔 앱에서 다음을 사용합니다. 파일 보관 일 수도 구성 가능하며 DateTime.Now의 AddDays () 메서드에서 사용하기 위해 -1을 곱합니다.

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

        }

0

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

0

와 솔루션이 있기 때문에 new FileInfo(filePath)쉽게 테스트 할 수없는, 내가 좋아하는 클래스 래퍼를 사용하는 것이 좋습니다 Directory, FilePath같은 :

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

0

이 작업을 수행하는 데 도움이 될 수있는 작은 삭제 기능을 생성하기 만하면이 코드를 테스트했으며 완벽하게 실행됩니다.

이 기능은 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.