【问题标题】:Filter GetFiles() on multiple criteria根据多个条件过滤 GetFiles()
【发布时间】:2014-12-14 23:59:18
【问题描述】:

不知道如何措辞我的问题标题。但希望这会很快。

我在一个文件夹中有一堆 PDF 文件,我想获取某种类型文件的最近修改或创建日期。我的代码有效,但它给了我所有 PDF 文件的结果。我只想要某些名称的结果。

例如。在我的“c:\temp\”中,我有一些 PDF 文件,它们以几乎相同的 3 个首字母开头,后跟数字或更多字母。

文件名,例如 tes8796、fes8897895、bas232。等等等等。我只想显示“fes”和“bas”文件的结果,我不想看到“tes”文件...

有什么想法吗?

我相信它应该看起来像这样 {"fes*.pdf", "Bas*.pdf"})

我的代码有效,(我只想得到“fes”和“bas”文件的结果。)

Dim pathx As String = "C:\temp\"
Dim directory = New DirectoryInfo(pathx)
Dim from_date As DateTime = DateTime.Now.AddHours(-24)
Dim to_date As DateTime = DateTime.Now
Dim files = directory.GetFiles().Where(Function(file) file.LastWriteTime >= from_date AndAlso file.LastWriteTime <= to_date)
For Each filx In files
    ListBox1.Items.Add(filx)
Next

【问题讨论】:

    标签: vb.net directoryinfo


    【解决方案1】:

    有多种方法可以做到这一点。首先,您可以在开头应用 PDF 过滤器:directory.GetFiles("*.pdf"),然后只需扩展您的功能条件:

    Dim names() As String = {"fes", "bas"}
    
    Dim files = di.GetFiles("*.pdf").Where(
            Function(file) (file.LastWriteTime >= from_date _ 
                   AndAlso file.LastWriteTime <= DateTime.Now) _
                      AndAlso (names.Contains(file.Name.ToLowerInvariant.Substring(0, 3)))
                )
    
    For Each filx In files
        Console.WriteLine(filx)
    Next
    

    问题在于它取决于文件的起始名称始终是 3 个字符。另外,看看你的代码:一旦你得到你的数组,你就会循环通过它把它发布到 ListBox。 通常酷孩子使用 LINQ 来避免循环。因此,要解决这两个问题:

    ListBox1.Items.AddRange(di.GetFiles("*.pdf").Where(
            Function(f) (f.LastWriteTime >= from_date AndAlso f.LastWriteTime <= DateTime.Now) _
                AndAlso names.Any(Function(n) f.Name.ToLowerInvariant.StartsWith(n))
                ).ToArray)
    

    我摆脱了 NET 中已经存在的变量名称,例如 Directory 和 File。第二个函数过滤名称数组,然后将结果直接泵入列表框项集合。

    在几乎所有情况下,普通循环会更快:

    Dim myfiles = directory.GetFiles("*.pdf")
    For Each f In myfiles
        If f.LastAccessTime >= from_date AndAlso f.LastWriteTime <= DateTime.Now Then
            For Each s As String In names
                If f.Name.ToLowerInvariant.StartsWith(s.ToLowerInvariant) Then
                    Console.WriteLine(f)
                    Exit For                     ' abort when found
                End If
            Next
        End If
    Next
    
    • 对于一个自称是VB.NET 新手的人来说可能更容易理解
    • 这可以增量调试
    • 处理速度提高 2 到 100 倍(取决于文件数量和名称过滤器)a
    • 适用于不同的文件名过滤器
    • 将查找/过滤操作与发布相结合,以消除额外的循环(Console.WriteLine 可以根据需要添加到项目或添加到列表。)

    a 时差是否重要取决于它的使用方式和负载。如果它连续运行以处理很多很多文件,它可能很重要。作为桌面应用程序的一部分,可能不会。

    【讨论】:

      【解决方案2】:

      您调用的GetFiles 方法已重载,允许您指定要匹配的单个模式。您可以调用该方法两次(每个模式一次),然后组合结果,或者您可以按原样通过一次调用检索所有文件,然后将另一个条件添加到您的 Where 调用以过滤任何名称以及日期/时间。

      【讨论】:

      • 我想的差不多了,但在 VB 方面我还是个新手。所以也许你可以编辑我必须得到我想要的结果吗?此外,将有更多的文件名,而不仅仅是两个。谢谢
      【解决方案3】:

      你们很亲密。我会这样做:

          Dim pathx As String = "C:\temp\"
          Dim directory = New IO.DirectoryInfo(pathx)
          Dim from_date As DateTime = DateTime.Now.AddHours(-24)
          Dim to_date As DateTime = DateTime.Now
          Dim files = directory.GetFiles().Where(Function(file) file.LastWriteTime >= from_date AndAlso file.LastWriteTime <= to_date AndAlso file.Name.EndsWith(".pdf") AndAlso (file.Name.StartsWith("fes") OrElse file.Name.StartsWith("bas")))
          For Each filx In files
              ListBox1.Items.Add(filx)
          Next
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        • 2018-08-24
        • 2020-08-29
        • 2021-03-05
        • 2021-01-27
        • 1970-01-01
        • 2014-08-12
        相关资源
        最近更新 更多