【问题标题】:Faster way to find large files with Python?使用 Python 查找大文件的更快方法?
【发布时间】:2018-02-19 01:27:43
【问题描述】:

我正在尝试使用 Python 找到一种更快的方法来筛选包含大约 9 个其他目录的大目录(大约 1.1TB)并在多个 linux 服务器上查找大于 200GB 或类似文件的文件,并且它必须是 Python。

我已经尝试过很多方法,例如使用脚本调用 du -h,但 du 太慢了,无法通过 1TB 大的目录。 我也尝试过 find ./ +200G 之类的 find 命令,但这也将永远持续下去。

我也尝试过 os.walk() 和 .getsize() 但这是同样的问题 - 太慢了。 所有这些方法都需要数小时和数小时,如果有人能够帮助我,我需要帮助找到另一种解决方案。因为我不仅要在一台服务器上搜索大文件,而且我必须通过近 300 台服务器进行 ssh 并输出所有大于 200GB 的文件的巨大列表,而且我尝试过的三种方法都不会能够做到这一点。 任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 不幸的是,没有办法这样做。例如,一个名为 Everything 的程序为您的整个驱动器编制索引,您可以根据过滤器对文件进行排序。即使是这个程序也找不到这种“快捷方式”。 Python 应该没有什么不同。使用不同的语言也不会改变任何东西,因为 os.walk 和 .getsize() 主要依赖于操作系统,并且主要运行非 Python 代码。
  • 我不认为 python 会提高你的磁盘读取速度。我认为您正在寻找的是并行化,以便您可以同时检查每台服务器。那么总共应该只需要几个小时。
  • @RobertSeaman 我对并行化概念不是很熟悉,是否有任何信息链接可以发送给我?

标签: python linux


【解决方案1】:

很难想象您会找到比os.walk()du 更快的遍历目录的方法。在某些设置(例如 SSD)中,并行化搜索可能会有所帮助,但不会产生显着差异。

一种让事情变得更快的简单方法是每隔一小时左右在后台自动运行脚本,然后让您的实际脚本获取结果。如果结果需要是最新的,这将无济于事,但可能适用于许多监控设置。

【讨论】:

    【解决方案2】:

    这不是真的,你不能比os.walk()做得更好

    scandir 据说要快 2 到 20 倍。

    来自https://pypi.python.org/pypi/scandir

    Python 的内置 os.walk() 比它需要的慢得多,因为除了在每个目录上调用 listdir() 之外,它还在每个文件上调用 stat() 以确定文件名是否为目录或不。但是 Windows 上的 FindFirstFile / FindNextFile 和 Linux/OS X 上的 readdir 都已经告诉您返回的文件是否是目录,因此不需要进一步的 stat 系统调用。简而言之,您可以将系统调用的数量从大约 2N 减少到 N,其中 N 是树中文件和目录的总数。

    实际上,删除所有这些额外的系统调用会使 os.walk() 在 Windows 上快 7-50 倍,在 Linux 和 Mac OS X 上快约 3-10 倍。所以我们不是在谈论微优化。

    从 python 3.5 开始,感谢PEP 471scandir 现在是内置的,在os 包中提供。小型(未经测试)示例:

    for dentry in os.scandir("/path/to/dir"):
        if dentry.stat().st_size > max_value:
           print("{} is biiiig".format(dentry.name))
    

    (当然你在某些时候需要stat,但是使用os.walk你在使用函数时隐式调用stat另外,如果文件有一些特定的扩展名,你可以只执行stat当扩展匹配时,节省更多)

    还有更多:

    所以,除了提供一个scandir()迭代器函数直接调用之外,Python现有的os.walk()函数也可以大大加速。

    因此,迁移到 Python 3.5+ 可以神奇地加快 os.walk,而无需重写代码。

    根据我的经验,在网络驱动器上多次调用 stat 在性能方面是灾难性的,因此,如果您的目标是网络驱动器,那么您将比本地磁盘用户受益于这种增强。

    不过,在网络驱动器上获得性能的最佳方法是在本地安装驱动器的机器上运行扫描工具(例如使用 ssh)。虽然不太方便,但值得。

    【讨论】:

    • 2x 到 20x speedupapplies to Windows, not to Linux (which the OP tagged). For the OP it is not enough to tell apart files from directories, the code must actually stat` 文件。此外,OP 很清楚du 也太慢了,这已经尽可能地优化了目录遍历。 scandir不会有“神奇的加速”,必须改变策略。
    • "但是 Windows 上的 FindFirstFile / FindNextFile 和 Linux/OS X 上的 readdir 已经告诉你返回的文件是否是目录,所以不需要进一步的 stat 系统调用。简而言之,所以加速适用到 linux 也是如此。但是如果du 已经很慢了,是的,问题可能出在其他地方,我编辑了我的结论。
    • 正如我所说,OP 仅将文件与目录区分开来是不够的,还需要获取文件的大小。我想如果层次结构中有很多目录和很少的文件,可能会有一个小的加速,这将消除stat 已知是目录的条目的需要。但这似乎并非不可能,即便如此,它也不会对所展示的用例产生影响。
    • 我不能再同意了,但正如我在回答中提到的那样,如果有办法通过名称将大文件与其他文件区分开来(例如:*.bin),这并不少见,那么时间可以被保存,甚至与du相比。
    猜你喜欢
    • 2021-06-14
    • 2021-02-20
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 2022-11-25
    相关资源
    最近更新 更多