【问题标题】:Why does os.scandir() slow down/ how to reorganize huge directory?为什么 os.scandir() 变慢/如何重组巨大的目录?
【发布时间】:2021-06-15 22:10:04
【问题描述】:

我有一个目录,其中包含超过 300 万个文件(我应该一开始就避免创建)。使用 os.scandir() 简单地打印出名称,

for f in os.scandir():
    print(f)

对于前 200,000 个文件,每个项目需要 0.004 秒,但会大幅减慢到每个项目 0.3 秒。再次尝试时,它还是做了同样的事情——前约 200,000 人快速,然后慢下来。

等待一个小时后再次运行它,这一次它对于前约 400,000 个文件来说很快,但随后以同样的方式变慢。

这些文件都是从 1908 年到 1963 年之间的一年开始的,所以我尝试使用 bash 命令重新组织文件,例如

for i in {1908..1963}; do 
> mkdir ../test-folders/$i; 
> mv $i* ../test-folders/$i/; 
> done

但它最终会被挂断并且永远无法到达任何地方......

关于如何重新组织这个巨大的文件夹或更有效地列出目录中的文件有什么建议吗?

【问题讨论】:

    标签: python operating-system scandir


    【解决方案1】:

    听起来最好使用迭代器,一个一次只返回一个项目而不是将所有内容都放入内存的函数。

    glob 库具有函数iglob

    for infile in glob.iglob( os.path.join(rootdir, '*.*') ):
        …
    

    文档:https://docs.python.org/3/library/glob.html#glob.iglob

    相关问答:https://stackoverflow.com/a/17020892/7838574

    【讨论】:

      【解决方案2】:

      哎呀。那是很多文件。我不确定为什么 python 开始变慢,这很有趣。但是你遇到问题的原因有很多。第一,目录可以被认为是一种特殊类型的文件,它只保存其中所有文件的文件名/数据指针(非常简化)。当操作系统将某些信息缓存在内存中以加快整个系统的磁盘访问速度时,它可以更快地访问任何文件。

      python 变慢似乎很奇怪,也许你碰到了内部存储器或 python 中的一些其他机制。

      但是让我们解决问题的根源。您的 bash 脚本有问题,因为每次使用 * 字符时,您都在强制 bash 脚本读取整个目录(并且可能按字母顺序排序)。获取列表一次然后对列表的各个部分进行操作可能更明智。可能是这样的:

      /bin/ls -1 > /tmp/allfiles
      for i in {1908..1963}; do
          echo "moving files starting with $i"
          mkdir ../test-folders/$i
          mv $(egrep "^$i" /tmp/allfiles) ../test-folders/$i/
      done
      

      这将只读取一次目录(有点),并会告诉你它的速度有多快。

      【讨论】:

        猜你喜欢
        • 2020-04-03
        • 1970-01-01
        • 2017-11-27
        • 1970-01-01
        • 1970-01-01
        • 2015-03-15
        • 1970-01-01
        • 2020-08-26
        • 2013-07-06
        相关资源
        最近更新 更多