ディレクトリの中から最新の更新時刻のファイルを取得する

タイトルの通りですが、あるディレクトリ(フォルダ)の中から最新の更新時刻、つまり一番最後に内容を更新したファイルを 1件だけ取得する実装例です。

最近似たような処理を何度も書いた気がするので記事にしてみました。

確認環境

この記事は以下の環境で動作確認を行っています。

  • ViauslStudio 2019(16.10.4)
  • .NET Core 5 + C# 9.0

実装コード

まずは実装コードの紹介です。

DirectoryUtil クラス

最新のものを取得するだけでも良かったのですが逆の動作をする処理も実装しています。各々の説明は以下の通りです。

メソッド名 説明
GetLatestFile ディレクトリの中から最新の更新時刻のファイルを1件取得する
GetOldestFile ディレクトリの中から一番古い更新時刻のファイルを1件取得する
using System;
using System.IO;

namespace Takap.Utility
{
    public static class DirectoryUtil
    {
        /// <summary>
        /// 指定したディレクトリの中から更新時刻が一番新しいファイルを取得します。
        /// </summary>
        /// <returns>
        /// 最新のファイルパス。
        /// ただしディレクトリにファイルが1つも無ければ空文字を返す。
        /// </returns>
        public static string GetLatestFile(string dir)
        {
            return core(dir, (path, file)
                => File.GetLastWriteTime(path) > File.GetLastWriteTime(file));
        }

        /// <summary>
        /// 指定したディレクトリの中から更新時刻が一番古いファイルを取得します。
        /// </summary>
        /// <returns>
        /// 最新のファイルパス。
        /// ただしディレクトリにファイルが1つも無ければ空文字を返す。
        /// </returns>
        public static string GetOldestFile(string dir)
        {
            return core(dir, (path, file) 
                => File.GetLastWriteTime(file) > File.GetLastWriteTime(path));
        }

        private static string core(string dir, Func<string, string, bool> compare)
        {
            if (!Directory.Exists(dir))
                throw new DirectoryNotFoundException($"Directory not found. path={dir}");

            string file = "";
            foreach (string path in Directory.GetFiles(dir))
            {
                if (string.IsNullOrEmpty(file))
                {
                    file = path;
                }
                else
                {
                    if (compare(path, file))
                    {
                        file = path;
                    }
                }
            }
            return file;
        }
    }
}

使い方

上記処理の使い方は以下の通りです。唯一ディレクトリが空の場合、戻り値の string が共通して空文字列になるためチェックしてからパスを参照します。

internal class AppMain
{
    public static void Main(string[] args)
    {
        string filePath = FileUtil.GetLatestFile(@"D:\Sample");
        
        // ディレクトリが空だとファイルパスが取れないのでチェックする
        if(!string.IsNullOrEmpty(filePath))
        {
            Console.WriteLine(filePath); // 一番新しいファイルのパス
        }
    }
}

以上です。