【问题标题】:C# FileInfo - additional conditions in this LINQ queryC# FileInfo - 此 LINQ 查询中的附加条件
【发布时间】:2021-02-21 19:22:49
【问题描述】:

我正在尝试在此类中创建一个方法,该方法在调用时将扫描 Documents 文件夹的所有子文件夹,找到任何名为“Log”的子文件夹,并在这些 Log 文件夹中找到任何扩展名为 .log 的文件,并且在过去 24 小时内创建或修改过。这是我到目前为止所拥有的。假设传入方法的string path参数是C:\Users\Me\Documents:

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

namespace FileFinder
{
    class ModifiedFileFinder
    {
        static public IEnumerable<FileInfo> GetFilesModifiedInLast24Hours(string path)
        {
            var directory = new DirectoryInfo(path);
            DateTime from_date = DateTime.Now.AddDays(-1);
            DateTime to_date = DateTime.Now;
            var files = directory.GetFiles("*.*", SearchOption.AllDirectories)
              .Where(file => file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);
            return files.ToList();    
        }
    }
}

我相信我已经处理了“过去 24 小时”的要求,但我正在苦苦挣扎的是如何表明我只希望 GetFiles 方法在名为 Log 的子文件夹中查找,并且仅适用于带有 .txt 的文件扩展名。

编辑#1:

在@Jimi 下面的评论的帮助下,我离我更近了,但似乎少了一步。这是更新的代码:

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

namespace CGLogFiles
{
    class ModifiedFileFinder
    {
        static public IEnumerable<FileInfo> GetFilesModifiedInLast24Hours(string path)
        {
            var directory = new DirectoryInfo(path);
            DateTime from_date = DateTime.Now.AddDays(-1);
            DateTime to_date = DateTime.Now;
            var files = directory.EnumerateFiles("*.log", SearchOption.AllDirectories)
              .Where(file => file.Directory.Name.Equals("Log") && file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);

            return files.ToList();
        }
    }
}

现在的问题是,尽管有SearchOption.AllDirectories 参数,但该方法肯定不在子目录中查找。它仅从顶级目录返回文件。有什么想法吗?

【问题讨论】:

  • 您可以添加条件:file.Directory.Name.Equals("Log")。过滤器在GetFiles("*.txt", ...) 中指定。您可能应该使用EnumerateFiles()yield return...。或者先EnumerateDirectories(),然后是内容。 --- IMO,&amp;&amp; file.LastWriteTime &lt;= to_date 不是必需的。
  • DirectoryInfo.EnumerateFiles() 想要包含的文件类型的过滤器作为第一个参数;所以,既然你想找到.txt 文件,那么DirectoryInfo.EnumerateFiles("*.txt", SearchOption.AllDirectories)。 -- 请注意SearchOption.AllDirectories 可能是危险的:枚举目录树可能需要很长时间。仅当您确定路径不包含重解析点等时才使用它(因此您永远不会在AppData 或当前用户主文件夹等中使用它)
  • 确实如此。该代码查找具有.log 扩展名的文件,其中直接父文件夹名称为Log:例如C:\Users\Me\Documents\Log\somefile.logC:\Users\Me\Documents\SomeFolder\Log\someOtherFile.log 等。如果这不是您要查找的目录结构,请发布一些示例。
  • 我很确定这个过程会以这种方式查看目录树。看到应该搜索的文件夹结构上有一个协议。例如,它不会找到C:\Users\Me\Documents\SomeFolder\Log\Other\someOtherFile.log
  • 好的。你也考虑过这种情况吗? LoglogLOG 是不同的,您正在寻找的只是 Log。如果目录名称可以有不同的大小写,请改用file.Directory.Name.Equals("LOG", StringComparison.InvariantCultureIgnoreCase)。文件扩展名不区分大小写。

标签: c# linq fileinfo


【解决方案1】:

您可以使用递归查找所有名为“Log”的子文件夹

    static void Main(string[] args)
    {
        const string path = @"C:\Logs\Test";

        var files = GetFilesModifiedInLast24Hours(path);

        Console.ReadLine();
    }

方法:GetFilesModifiedInLast24Hours

    public static IEnumerable<FileInfo> GetFilesModifiedInLast24Hours(string path)
    {

        var toDate = DateTime.Now;
        var fromDate = toDate.AddDays(-1);

        var fileInfos = new List<FileInfo>();

        var directoryPaths = GetFolders(path);

        const string fileExtension = "*.txt";
        foreach (var directoryPath in directoryPaths)
        {
            var directory = new DirectoryInfo(directoryPath);
            
            var files = directory.GetFiles(fileExtension)
                .Where(file => file.LastWriteTime >= fromDate && file.LastWriteTime <= toDate)
                .ToList();

            if (files.Any())
            {
                fileInfos.AddRange(files);
            }
        }


        return fileInfos;
    }

递归函数查找所有名为“Log”的子文件夹

   private static List<string> GetFolders(string folderPath)
    {
        const string folderToFind = "Log";

        var folders = new List<string>();
        var paths = Directory.GetDirectories(folderPath);

        foreach (var path in paths)
        {
            var directoryName = new DirectoryInfo(path).Name;
            if (directoryName == folderToFind)
            {
                folders.Add(path);
            }

            if (!IsDirectoryEmpty(path))
            {
                var subDirectory = GetFolders(path);
                if (subDirectory.Any())
                {
                    folders.AddRange(subDirectory);
                }
            }
        }

        return folders;
    }

验证文件夹是否包含子文件夹的功能

private static bool IsDirectoryEmpty(string path)
{
        return !Directory.EnumerateFileSystemEntries(path).Any();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2014-11-25
    • 2021-08-07
    相关资源
    最近更新 更多