ลบไฟล์ที่เก่ากว่า 3 เดือนในไดเร็กทอรีโดยใช้. NET


119

ฉันอยากทราบ (โดยใช้ C #) ฉันจะลบไฟล์ในไดเร็กทอรีที่เก่ากว่า 3 เดือนได้อย่างไร แต่ฉันเดาว่าช่วงวันที่อาจยืดหยุ่นได้

เพื่อความชัดเจน: ฉันกำลังมองหาไฟล์ที่เก่ากว่า 90 วันหรืออีกนัยหนึ่งคือไฟล์ที่สร้างน้อยกว่า 90 วันที่ผ่านมาควรถูกเก็บไว้ไฟล์อื่น ๆ ทั้งหมดจะถูกลบ


หากมีจำนวนไฟล์ที่สำคัญวิธีที่ดีที่สุดคือใช้ EnumerateFiles และ EnumerateDirectories แทน GetFiles และ GetDirectories เนื่องจากไฟล์เหล่านี้เรียกใช้การแจงนับโดยตรงแทนที่จะรวบรวมรายการ อย่างไรก็ตามคุณจะต้องใช้ foreach loop
Larry

คำตอบ:


259

บางสิ่งบางอย่างเช่นนี้ทำมัน

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.

11
ไม่เป็น propertyNames กล่าวว่า: LastAccessTime- คุณควรไปหาทรัพย์สินCreationTimeถ้าคุณต้องการ!
Andreas Niedermair

4
ใช่คุณสมบัติที่คุณใช้ขึ้นอยู่กับคุณทั้งหมด คุณยังสามารถใช้ LastWriteTime ได้หากต้องการ
Steve Danner

3
+1 สำหรับการช่วยเหลือฉัน แทนที่จะสร้างอินสแตนซ์ FileInfo ใหม่คุณสามารถใช้ File.GetCreationTime หรือ File.GetLastAccessTime ควรปรับปรุงประสิทธิภาพเล็กน้อย
Mario The Spoon

5
ฉันเดาว่า GetFiles และ Delete ไม่เคยล้มเหลวในสภาพแวดล้อมของคุณ? เพียงแค่ชี้ให้เห็นว่าเนื่องจากสิ่งนี้ดูเหมือนจะเป็นคำตอบที่มีการอ้างอิงสูง
Andrew Hagner

94

นี่คือแลมด้า 1 ซับ:

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

@VladL ฉันได้รับ "IEnumerable <FileInfo> ไม่มี ForEach" ถ้าฉันวาง ToList () ฉันแค่เก็บมันไว้
James Love

3
ฉันชอบสิ่งนี้. แต่ฉันจะสรุปการลบในการลอง / จับ
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 = DirectoryInfo ใหม่ (@ "C: \ Temp") GetFiles () โดยที่ (x => x.LastAccessTime <DateTime.Now.AddMonths (-3)); // รูปแบบ
Ta01

2
Woho! คนอื่นที่ไม่ใช่ฉันคิดว่าการใช้ 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))ไม่มีเหตุผลที่จะคำนวณสิ่งนั้นซ้ำ ๆ ในลูป
ชาด


1

โดยทั่วไปคุณสามารถใช้ Directory.Getfiles (Path) เพื่อรับรายการไฟล์ทั้งหมด หลังจากนั้นให้คุณวนซ้ำรายการและเรียก GetLastAccessTim () ตามที่ Keith แนะนำ


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 ของไฟล์อัปเดตหลังจากเข้าถึง


0

คุณแค่ต้องการFileInfo -> CreationTime

และมากกว่าการคำนวณความแตกต่างของเวลา

ใน app.config คุณสามารถบันทึกTimeSpanค่าของอายุไฟล์ที่ต้องลบ

ตรวจสอบการลบวันที่และเวลาด้วยวิธีการวันที่และเวลา

โชคดี



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 วันต่อสัปดาห์และเป็นสี่ชั่วโมง

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 จำนวนวันในการเก็บไฟล์ยังสามารถกำหนดค่าได้คูณด้วย -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();
                }
            }

        }

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

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.