如何解决为什么 os.scandir() 变慢/如何重新组织大目录?
我有一个包含 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
但它最终被挂断了,永远无法到达任何地方......
关于如何重新组织这个巨大的文件夹或更有效地列出目录中的文件的任何建议?
解决方法
这听起来像使用迭代器,一个一次只返回一个项目而不是把所有东西都放在内存中的函数,是最好的。
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
,哦。那是很多文件。我不确定为什么 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
这只会读取目录一次(有点),并会通知您它的运行速度。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。