从每个目录获取最新文件

时间:2013-10-08 20:14:23

标签: c#

在论坛搜索后,我找到了我的问题的解决方案:我有根文件夹,我想从根文件夹下的每个目录中找到最新的文件:

    public static void FindNewestFile(string path)
    {
        List<string> list = getNewestFile(path);
        foreach (string dir in list)
        {
            DirectoryInfo directory = new DirectoryInfo(dir);
            try
            {
FileInfo file = directory.GetFiles("*.*", SearchOption.AllDirectories).OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
                if (file != null)
                {
                    // Do things with my file
                }
            }
            catch (UnauthorizedAccessException)
            { }
        }
    }

  private static List<string> getNewestFile(string path)
    {
        List<string> list = new List<string>();
        foreach (string dir in EnumerateFoldersRecursively(path))
        {
            list.Add(dir);
        }

        return list;
    }

    private static IEnumerable<string> EnumerateFoldersRecursively(string root)
    {
        foreach (var folder in EnumerateFolders(root))
        {
            yield return folder;

            foreach (var subFolder in EnumerateFoldersRecursively(folder))
            {
                yield return subFolder;
            }
        }
    }

    private static IEnumerable<string> EnumerateFolders(string root)
    {
        WIN32_FIND_DATA findData;
        string spec = Path.Combine(root, "*");

        using (SafeFindHandle findHandle = FindFirstFile(spec, out findData))
        {
            if (!findHandle.IsInvalid)
            {
                do
                {
                    if ((findData.cFileName != ".") && (findData.cFileName != ".."))  // Ignore special "." and ".." folders.
                    {
                        if ((findData.dwFileAttributes & FileAttributes.Directory) != 0)
                        {
                            yield return Path.Combine(root, findData.cFileName);
                        }
                    }
                }
                while (FindNextFile(findHandle, out findData));
            }
        }
    }

我的问题是它绕过了根目录而没有从这个目录返回最新的文件

3 个答案:

答案 0 :(得分:2)

稍微更改您的代码即可添加此行:

List<string> list = getNewestFile(path);
list.Add(path);              //Add current directory to list as well
foreach (string dir in list) //..etc

应该是我说的最容易解决的问题。

答案 1 :(得分:1)

如果您想拥有所有文件的列表,可以执行以下操作:

string[] filePaths = Directory.GetFiles(@"c:\MyDir\", SearchOption.AllDirectories);

然后你可以将te数组与其他旧数组进行比较,以查看是否有新文件或文件是否已删除

答案 2 :(得分:0)

哇,这是很多代码,你可以让.Net的BCL课程(以及Linq)做重任......

这应该足够了:

public IEnumerable<FileInfo> GetNewestFilePerDirectory(
    string root,
    string pattern = "*",
    SearchOption searchoption = SearchOption.TopDirectoryOnly
)
{
    return new DirectoryInfo(root)
        .EnumerateFiles(pattern, searchoption)
        .GroupBy(g => g.Directory.FullName)
        .Select(s => s.OrderBy(f => f.Name)
            .First(f => f.CreationTimeUtc == s.Max(m => m.CreationTimeUtc))
        );

}

一个简单的控制台应用程序演示/文档,将点放在i:

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

class Program
{
    private static void Main(string[] args)
    {
        var newestfiles = GetNewestFilePerDirectory(
            @"D:\foo\bar", "*", SearchOption.AllDirectories
        );

        Console.WriteLine(string.Join("\r\n", newestfiles.Select(f => f.FullName)));
    }

    /// <summary>
    ///     Scans a directory (and, optionally, subdirectories) and returns an
    ///     enumerable of <see cref="FileInfo"/> for the newest file in eacht
    ///     directory.
    /// </summary>
    /// <param name="root">
    ///     A string specifying the path to scan.
    /// </param>
    /// <param name="pattern">
    ///     The search string. The default pattern is "*", which returns all files.
    /// </param>
    /// <param name="searchoption">
    ///     One of the enumeration values that specifies whether the search operation should
    ///     include only the current directory or all subdirectories. The default value is
    ///     <see cref="SearchOption.TopDirectoryOnly"/>.
    /// </param>
    /// <returns>
    ///     Returns the newest file, per directory.
    /// </returns>
    /// <remarks>
    ///     For directories containing files of the same createtiondate, the first file when
    ///     sorted alphabetical will be returned.
    /// </remarks>
    private static IEnumerable<FileInfo> GetNewestFilePerDirectory(
        string root,
        string pattern = "*",
        SearchOption searchoption = SearchOption.TopDirectoryOnly
    )
    {
        return new DirectoryInfo(root)
            .EnumerateFiles(pattern, searchoption)
            .GroupBy(g => g.Directory.FullName)
            .Select(s => s.OrderBy(f => f.Name)
                .First(f => f.CreationTimeUtc == s.Max(m => m.CreationTimeUtc))
            );

    }
}