.NETを使用して、ディレクトリ内の3か月より古いファイルを削除する


117

(C#を使用して)3か月以上前の特定のディレクトリにあるファイルを削除する方法を知りたいのですが、日付の期間は柔軟であると思います。

明確にするために:私は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を使用することもできます。
スティーブダナー

3
助けてくれて+1。新しいFileInfoインスタンスを作成する代わりに、File.GetCreationTimeまたはFile.GetLastAccessTimeを使用できます。パフォーマンスのマイナーな改善になるはずです。
マリオザスプーン

5
GetFilesとDeleteが環境で失敗することはないと思いますか?これは非常に参照されている回答のようですので、指摘してください。
Andrew Hagner 2013年

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>にForEachが含まれていない」というメッセージが表示されます。私はちょうどそれを保管。
ジェームス・ラブ

3
私はこれが好き。しかし、私はtry / catchで削除をラップします
H20rider

new DirectoryInfo(dir).GetFiles()new FileInfo(f)すべての単一ファイルよりも高速です。
VojtěchDohnal

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)); //バリエーション
Ta01

2
わほ!LINQの使いすぎは素晴らしいと私以外の誰かが考えています!;)
Filip Ekberg、2010

.ToList()呼び出しは、一致したファイルを介した2番目のループ以外に何を追加しますか?
Joel Mueller

2
@ジョエル・ミュラー。 すべての要素にを適用するために使用できるメソッドをList<T>定義ForEachしますAction<T>。残念ながら、にはそのような拡張メソッドはありませんIEnumerable<T>
Samuel Neff

1
いい視点ね。私は自分の書いたForEachために拡張メソッドをIEnumerable<T>。私は時々それが組み込まれていないことを忘れ、少し前
ジョエルミューラー

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 Sa​​vard、2010

4
foreach()の値を保持するには、ループの外で新しい変数を宣言する必要があり(DateTime.Now- new TimeSpan(90, 0, 0, 0))ます。ループで繰り返し計算する理由はありません。
チャド


1

基本的に、Directory.Getfiles(Path)を使用して、すべてのファイルのリストを取得できます。その後、リストをループして、キースの提案どおりに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か月
ダニエル

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

ページの読み込み、Webサービス、またはその他の用途で使用します。

私のコンセプトは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つのフォルダーをアップする必要があります。私はこのアルゴリズムを週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)は簡単にテストできないためDirectoryFileなどのクラスには次のようにラッパーを使用することをお勧めします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.