我有一大堆文件位于Windows 2003服务器上的一系列目录中。每个目录中有超过一百万个文件。 Windows服务器使用iSCSI连接到Equalogics SAN。
我有一个应用程序需要确定是否存在一组文件 - 应用程序需要检查每个目录是否存在多达一百万个文件。
我尝试了各种技术/脚本语言,包括perl,vbscript,dos批处理文件,我每秒不能获得超过250个文件检查。这可以用来将近50分钟来检查800,000个文件。我尝试多线程一个perl程序来一次检查多个文件,但这没有帮助。
我还尝试使用dir,ls,find(通过cygwin)列出目录中的所有文件,并且它开始输出任何文件名需要很长时间。无论如何,这不是一个好方法,因为文件比我实际需要检查的文件多。
有没有办法可以强制Windows在目录上执行“预读”,并将文件放入缓存中?
有没有更好的方法来解决这个问题?
答案 0 :(得分:0)
我可能会避免使用任何解释性语言,例如VBScript等,正是因为你指定的原因 - 在性能问题的情况下不能正常工作。
现在,正如我对我的建议的正式警告一样,我假设在预期的时间内这样的应用程序会运行一组预测文件(搜索目标)保持相对稳定,以便存在误报存在的风险由于扫描应用程序启动后发生的文件集更改而导致的应用程序检查很少。
它并不优雅,但我至少建议探索一个Win32(不是.NET)控制台类型的应用程序,该应用程序以递归方式将目录树搜索到内存映射文件中,然后在该文件中搜索所需的模式。这将磁盘访问限制为累积结果所需的工作量,然后将搜索放在可能(更快)内存支持的文件上。现在,我可能低估了文件集内容的大小和/或复杂性,但这就是我提供的起点。
我建议在.NET应用程序上使用Win32应用程序以避免框架运行时的开销,但是有关非托管应用程序的明显警告适用。
希望这对你有所帮助,或者至少为你争取一些帮助。祝你好运。
答案 1 :(得分:0)
当您单独检查每个文件时,您会受到请求和响应延迟的限制。除非您使用异步请求并同时运行多个请求,否则您可以找到一种方法来加快速度,但这种方法会给文件系统带来压力。
虽然获得完整的目录列表似乎有些过分,但它可能是最快的方法,除非您的搜索列表比完整目录多小(比小100倍)。
答案 2 :(得分:0)
每次单独检查都要求操作系统读取目录,直到找到(或找不到)您要求的文件为止。换句话说,每个检查平均读取目录内容的一半以上,因此读取整个目录几乎肯定会更有效。
但是,你不应该通过产生另一个程序来做到这一点。使用FindFirstFile / FindNextFile或.NET等效项。您可以在找到时根据列表检查每个文件 - 您可能希望先组织列表,将其放在b树中或其他位置。
您可能希望使用FileIdBothDirectoryInfo选项而不是FindFirstFile / FindNextFile尝试使用GetFileInformationByHandleEx来查看哪个更快。