4

Ans: 这是使用 c# 代码从文件夹中获取最新文件名的一种解决方案

调用函数如下:

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

仅仅为了找到列表中最大的项目而进行整个排序是非常低效的。

您最好使用“MaxBy()”Linq 扩展之一来查找最大值,例如Jon Skeet 和其他人的 MoreLinq扩展。(完整的图书馆在这里。)

如果您使用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 回答