【问题标题】:Is there a way to enumerate files by creation time on an SMB share?有没有办法通过 SMB 共享上的创建时间来枚举文件?
【发布时间】:2020-11-18 08:07:03
【问题描述】:

我正在寻找一种在 SMB 远程共享上检索比特定日期/时间更新的文件的方法,所有这些都在 Windows 下工作。我一直在使用DirectoryInfo.EnumerateFiles(),并在返回它们时进行过滤。不幸的是,这意味着在我查看之前,每条文件记录都会通过网络发送,并且随着文件列表的增长,情况会变得越来越糟。

我一直在与第三方供应商合作,因此我无法选择删除旧文件,也无法在我正在读取的文件服务器上运行任何代码。

我已经能够通过 p/调用 FindFirstFileEx/FindNextFile 并使用 FindExInfoBasicFIND_FIRST_EX_LARGE_FETCH 标志获得一些临时改进,但理想情况下,我想将日期时间过滤器卸载到服务器,只通过网络发送我需要的文件记录。是否有一些我只是没有发现可以提供帮助的 API?

【问题讨论】:

  • fs 仅支持按名称掩码过滤,但不支持按时间过滤。您还可以通过直接致电NtQueryDirectoryFile 进行改进
  • @RbMm,这就是它的样子。不幸的是,网络延迟浪费了太多时间,任何不解决往返次数的问题都不会产生重大影响。在本地驱动器上枚举需要不到一秒钟的时间在此网络上需要几个小时。
  • NtQueryDirectoryFile 比较 FindFirstFileExW 有 2 个优点 - FindFirstFileExW 总是对 NtQueryDirectoryFile 和 main 进行 1 次额外调用 - 使用 NtQueryDirectoryFile 您可以控制缓冲区大小 - 大缓冲区 - 更多文件缓冲区,更少的调用次数。如果您需要按时间过滤 - 您可能需要在服务器端拥有自我代理并向该代理发送查询
  • 谢谢 - 我会看看我能用它做什么!
  • @ThomasKoelle 和 PowerShell 能给你什么?无论如何,内部的 any 方法将使用 NtQueryDirectoryFile[Ex]。结果,没有什么比 NtQueryDirectoryFile[Ex] 更快了

标签: c# windows winapi smb


【解决方案1】:

SMB 协议本身允许创建一个SMB2 QUERY_DIRECTORY Request,它会得到一个SMB2 QUERY_DIRECTORY Response 的回答。根据 SMB 协议规范,您应该能够获取目录的文件列表,其中仅包含您需要的最少信息集(“FileInformationClass”)并以大块的形式传输它们。

要了解如何实现它,我会看一下SharpCifs.Std的源代码。

【讨论】:

    【解决方案2】:

    你试过了吗?

    DirectoryInfo DirInfo = new DirectoryInfo(@"\\archives1\library\");
    
    DateTime StartOf2009 = new DateTime(2009, 01, 01);
    
    // LINQ query for all files created before 2009.
    var files = from f in DirInfo.EnumerateFiles()
           where f.CreationTimeUtc < StartOf2009
           select f;
    
    // Show results.
    foreach (var f in files)
    {
      Console.WriteLine("{0}", f.Name);
    }
    

    【讨论】:

    • 不会改变您仍在枚举文件的事实,而这正是 Eclipse 试图避免的。
    • 我希望它能够正常工作,并且 Linq 查询能够反向传播到源计算机,但这仍然会在开始按时间过滤之前获取每个文件信息记录。
    猜你喜欢
    • 2017-10-04
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多