代码之家  ›  专栏  ›  技术社区  ›  werk jlcv

如何快速删除数百万个文件

  •  5
  • werk jlcv  · 技术社区  · 6 年前

    我们使用BOOST1。63 boost::filesystem::remove_all(dir_to_remove) 删除包含数百万个文件(每个文件大小为1MB)的文件夹。“dir\u to\u remove”文件夹有子文件夹,每个子文件夹的文件数不超过1000个。删除所有文件需要10分钟以上。我们使用CentOS6。5.

    检查操作后。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++快速删除数百万个文件?

    4 回复  |  直到 6 年前
        1
  •  8
  •   3CxEZiVlQ    6 年前

    如果要释放所需的位置,最快的方法是将目录移动(或重命名)到同一分区上的另一个位置。然后,您的程序可以继续使用所需的位置,并在另一个线程(后台)中递归删除以前移动的目录。这个线程甚至可以以较低的优先级工作,因此删除特定目录看起来就像是一个即时的文件系统操作。

        2
  •  3
  •   Niall Douglas    6 年前

    是 啊 std::filesystem::directory_iterator 他身体很差。我希望在即将到来的 P1031 Low level file i/o (注:在2018年6月之前,WG21将不会直播)有一些可以很好地扩展到输入的东西,所以我们正在关注它。

    同时,我建议您使用 https://ned14.github.io/afio/ 这是P1031的参考实现 directory_handle::enumerate() 。此库可以轻松处理包含数百万甚至数千万文件的目录。一旦您有了要删除的条目列表,您需要遵循B+树友好的删除模式,即按字母顺序或索引节点顺序对其进行排序,然后执行以下操作之一:

    1. 取消与向前的第一个条目的链接。
    2. 向后取消与最后一个条目的链接。
    3. 从第一个入口断开链接,然后从最后一个入口断开链接,朝中心移动。

    我会针对您的特定归档系统对所有六种方法进行基准测试,并选择最快的方法。有些使用基于inode编号的B+树,有些使用基于leafname的B+树,这会有所不同。但基本上,您希望避免过度的树重新平衡,并避免对leafname进行深入的O(log N)查找,从而避免有序的取消链接。

        3
  •  1
  •   MSalters    6 年前

    您链接到的文章讨论了shell透视图。这一点至关重要:shell为许多任务启动程序。虽然启动一个程序非常便宜,但当你需要启动一百万个程序时,它可能会很贵。这就是为什么 rsync 非常有效;一次调用可以完成所有工作。

    这同样适用于您的程序。您只启动一次程序;成本只是您正在进行的所有系统调用。

    我检查了系统调用列表;没有允许您使用一个系统调用进行批量删除的系统调用,因此每个要删除的文件只能有一个系统调用。

        4
  •  -1
  •   Mikhail    6 年前

    根据存储体系结构的不同,您可以通过并行删除文件来提高速度。因此,将工作分配给 std::thread s、 或者,如果您想快速尝试,请使用OpenMP pragma。

    这就是我管理约200 TB存储箱的方式。

    注意,如果任何文件相互链接,可能会出现轻微的争用情况,但只要处理错误,就可以了。