4

回答: これは、C# コードを使用してフォルダーから最新のファイル名を取得するための 1 つのソリューションです。

関数を次のように呼び出します。

FileInfo newestFile = GetNewestFile(new DirectoryInfo(@"D:\DatabaseFiles"));

関数:

public static FileInfo GetNewestFile(DirectoryInfo directory)
        {
            return directory.GetFiles()
                .Union(directory.GetDirectories().Select(d => GetNewestFile(d)))
                .OrderByDescending(f => (f == null ? DateTime.MinValue : f.LastWriteTime))
                .FirstOrDefault();
        }

私の質問は、フォルダから最新のファイル名を取得する別の方法を教えてください。

4

2 に答える 2

4

リスト内の最大の項目を見つけるためだけに全体の並べ替えを行うのは、非常に非効率的です。

Jon Skeet などの MoreLinq など、「MaxBy()」Linq 拡張機能のいずれかを使用して最大値を見つけることをお勧めします。(完全なライブラリはここにあります。)

コードを使用するMaxBy()と、次のようになります。

public static FileInfo GetNewestFile(DirectoryInfo directory)
{
    return directory.GetFiles()
        .Union(directory.GetDirectories().Select(d => GetNewestFile(d)))
        .MaxBy(f => (f == null ? DateTime.MinValue : f.LastWriteTime));
}

理想的には、これを他の提案された回答と組み合わせます (つまりDirectory.EnumerateFiles()、再帰を行うオーバーロードを使用します)。

完全なコンソール アプリのサンプルを次に示します。「MaxBy()」メソッドは、古いバージョンの MoreLinq から取得され、多少変更されています。

using System;
using System.Collections.Generic;
using System.IO;

namespace Demo
{
    public static class Program
    {
        private static void Main()
        {
            string root = "D:\\Test"; // Put your test root here.

            var di = new DirectoryInfo(root);
            var newest = GetNewestFile(di);

            Console.WriteLine("Newest file = {0}, last written on {1}", newest.FullName, newest.LastWriteTime);
        }

        public static FileInfo GetNewestFile(DirectoryInfo directory)
        {
            return directory.EnumerateFiles("*.*", SearchOption.AllDirectories)
                .MaxBy(f => (f == null ? DateTime.MinValue : f.LastWriteTime));
        }
    }

    public static class EnumerableMaxMinExt
    {
        public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
        {
            return source.MaxBy(selector, Comparer<TKey>.Default);
        }

        public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
        {
            using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
            {
                if (!sourceIterator.MoveNext())
                {
                    throw new InvalidOperationException("Sequence was empty");
                }

                TSource max = sourceIterator.Current;
                TKey maxKey = selector(max);

                while (sourceIterator.MoveNext())
                {
                    TSource candidate = sourceIterator.Current;
                    TKey candidateProjected = selector(candidate);

                    if (comparer.Compare(candidateProjected, maxKey) > 0)
                    {
                        max = candidate;
                        maxKey = candidateProjected;
                    }
                }

                return max;
            }
        }
    }
}
于 2015-01-23T10:56:48.770 に答える
1

再帰を行うオーバーライドを使用できます(残りのコードは質問からのものです)

return directory.GetFiles("*", SearchOption.AllDirectories)
                .OrderByDescending(f => (f == null ? DateTime.MinValue : f.LastWriteTime))
                .FirstOrDefault(); 

より良いかもしれないEnumerateFilesもあります(遅延実行)

return directory.EnumerateFiles("*", SearchOption.AllDirectories)
                .OrderByDescending(f => (f == null ? DateTime.MinValue : f.LastWriteTime))
                .FirstOrDefault(); 
于 2015-01-23T10:48:25.967 に答える