我们使用BOOST1.63 boost::filesystem::remove_all(dir_to_remove)
删除包含数百万个文件的文件夹(每个文件的大小为1MB)。文件夹" dir_to_remove"有子文件夹,每个子文件夹不超过1000个文件。删除所有文件需要10分钟以上。我们使用CentOS6.5。
检查operations.cpp后,我们意识到BOOST实际上使用了Linux rmdir
和unlink
命令:
# define BOOST_REMOVE_DIRECTORY(P)(::rmdir(P)== 0)
# define BOOST_DELETE_FILE(P)(::unlink(P)== 0)
此article列出了几种在Linux上更有效地删除文件的方法。它建议使用rsync
。
如何使用C ++快速删除数百万个文件?
答案 0 :(得分:7)
如果要释放所需位置,最快的方法是将目录移动(或重命名)到同一分区上的另一个位置。然后,您的程序可以继续使用所需的位置,并在另一个线程(在后台)递归删除以前移动的目录。该线程甚至可以以较低的优先级工作,因此删除特定目录看起来就像是一个即时文件系统操作。
答案 1 :(得分:2)
是的,std::filesystem::directory_iterator
非常笨拙。我希望在即将到来的P1031 Low level file i/o中完全取代该设施(注意不会在WG21上直播到2018年6月),其中的东西可以很好地输入,所以我们就可以了。
与此同时,我建议你使用https://ned14.github.io/afio/这是P1031的参考实现,特别是directory_handle::enumerate()
。该库可以轻松处理数百万甚至数千万个文件的目录。一旦有了要删除的条目列表,就需要遵循B + -tree友好删除模式,即按字母或字节顺序对它们进行排序,然后执行以下操作之一:
我会针对您的特定文件系统对所有六种方法进行基准测试,并选择最快的方法。有些使用基于inode编号的B +树,有些基于leafname,它会有所不同。但基本上你想避免过多的树重新平衡,并避免对叶名的深O(log N)查找,因此有序的取消链接。
答案 2 :(得分:1)
您链接的文章讨论了shell透视图。这非常重要:shell启动了许多任务的程序。虽然启动程序非常便宜,但是当你需要启动一百万个程序时,它可能会很昂贵。这就是rsync
如此有效的原因;单个调用可以完成所有工作。
这同样适用于您的计划。你启动你的程序一次;成本只是你正在进行的所有系统调用。
我检查了系统调用列表;没有系统调用允许您使用一个系统调用进行批量删除,因此每个文件只能删除一个系统调用。
答案 3 :(得分:0)
根据存储架构,您可以通过并行删除文件来加速。因此,在std::thread
之间拆分工作,或者如果你想快速尝试,请使用OpenMP pragma。
这就是我管理~200 TB存储箱的方式。
注意,如果任何文件相互链接,可能会有轻微的竞争条件,但只要你处理错误就应该没问题。