Windows的快速文件/目录扫描方法?

时间:2008-12-29 07:47:12

标签: python windows

我正在寻找一种高性能方法或库,用于扫描磁盘或给定目录中的所有文件,并获取其基本统计信息 - 文件名,大小和修改日期。

我编写了一个python程序,使用os.walkos.path.getsize来获取文件列表,它工作正常,但速度不是很快。我注意到我下载的一个免费软件程序完成了相同的扫描,比我的程序快得多。

加快文件扫描的想法?这是我的python代码,但请记住,如果有更好的替代方案,我根本不会与os.walk结婚并且非常愿意使用其他API(包括Windows本机API)。

for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        ...

我还应该注意到我意识到python代码可能不会加速那么多;我对任何提供更快速度的原生API特别感兴趣。

9 个答案:

答案 0 :(得分:3)

好吧,我希望这是一个严重的I / O绑定任务。 因此,python方面的优化将是非常无效的;我能想到的唯一优化是访问/列出文件的一些不同方式,以减少文件系统的实际读取。 这当然需要对文件系统有深入的了解,这是我没有的,而且我不希望python的开发人员在实现os.walk时有所了解。

如何生成命令提示符,然后发出'dir'并解析结果? 这可能有点过分,但运气好的话,'dir'正在努力进行这样的优化。

答案 1 :(得分:3)

似乎os.walk在python 2.5中已经considerably improved,因此您可以检查是否正在运行该版本。

除此之外,someone has already compared the speed of os.walk to ls并注意到后者的明显进展,但不是在实际证明使用它的范围内。

答案 2 :(得分:2)

您可能希望查看某些Python版本控制系统(如Mercurial或Bazaar)的代码。他们花了很多时间来提出快速遍历目录树并检测更改的方法(或“查找有关文件的基本统计信息”)。

答案 3 :(得分:2)

在Ben Hoyt的github上使用scandir python模块(以前更好的行走)。

http://github.com/benhoyt/scandir

它比python walk快得多,但使用相同的语法。只需导入scandir并将os.walk()更改为scandir.walk()。而已。这是在python中遍历目录和文件的最快方法。

答案 4 :(得分:1)

当你查看os.walk的代码时,你会发现修剪的脂肪并不多。

例如,以下只是比os.walk更快的头发。

import os
import stat

listdir= os.listdir
pathjoin= os.path.join
fstat= os.stat
is_dir= stat.S_ISDIR
is_reg= stat.S_ISREG
def yieldFiles( path ):
    for f in listdir(path):
        nm= pathjoin( path, f )
        s= fstat( nm ).st_mode
        if is_dir( s ):
            for sub in yieldFiles( nm ):
                yield sub
        elif is_reg( s ):
            yield f
        else:
            pass # ignore these

因此,开销必须在os模块本身。您将不得不求助于直接进行Windows API调用。

查看Python for Windows Extensions

答案 5 :(得分:1)

我想知道您是否想要对I / O操作进行分组。

例如,如果您走的是包含数千个文件的密集目录树,您可以尝试尝试遍历整个树并存储所有文件位置,然后循环遍历(内存中)位置并获取文件统计。

如果您的操作系统将这两个数据存储在不同的位置(一个位置的目录结构,另一个位置的文件统计信息),那么这可能是一个重要的优化。

无论如何,这是我在进一步挖掘之前尝试的东西。

答案 6 :(得分:1)

Python 3.5刚刚介绍了os.scandir(请参阅PEP-0471),它避免了许多非必需的系统调用,例如stat()GetFileAttributes(),以提供更快的文件 - 系统迭代器。

os.walk()现在将使用os.scandir()作为其迭代器来实现,因此您应该在继续使用os.walk()的同时看到潜在的大型性能改进。

使用示例:

for entry in os.scandir(path):
   if not entry.name.startswith('.') and entry.is_file():
       print(entry.name)

答案 7 :(得分:0)

os.path模块也有一个目录树行走功能。我从来没有对它进行任何基准测试,但你可以尝试一下。但是,我不确定在Python中有比os.walk / os.path.walk更快的方式。

答案 8 :(得分:0)

这只是部分帮助,更像是指针;但是:

我相信你需要做以下事情:

fp = open("C:/$MFT", "rb")

使用包含SYSTEM权限的帐户,因为即使作为管理员,也无法打开NTFS文件系统的“主文件表”(一种inode表)。在你成功之后,你只需要在网上找到解释每个文件记录结构的信息(我相信它通常是每个磁盘文件1024个字节,其中包括文件的主要路径名),然后关闭用于超高速磁盘结构读取。