【问题标题】:how to merge 2 big files [closed]如何合并2个大文件[关闭]
【发布时间】:2012-11-04 20:29:42
【问题描述】:

假设我有 2 个文件,每个文件大小为 100G。我想将它们合并为一个,然后将它们删除。在linux中 我们可以使用

cat file1 file2 > final_file

但这需要读取 2 个大文件,然后再写入一个更大的文件。是否可以只将一个文件附加到另一个文件,这样就不需要 IO?由于文件的元数据包含文件的位置和长度,我想知道是否可以更改文件的元数据来进行合并,所以不会发生 IO。

【问题讨论】:

  • 找到解决这个问题的方法的人可能会发现“hungrycat”很有用。饥饿猫在标准输出上打印文件的内容,同时释放文件占用的磁盘空间:github.com/jwilk/hungrycat

标签: linux file merge


【解决方案1】:

你可以合并两个文件而不将一个文件写入另一个文件吗?

仅在晦涩的理论中。由于磁盘存储始终基于块,因此文件系统将内容存储在块边界上,如果第一个文件在块边界上完美结束,您只能将一个文件附加到另一个文件而无需重写。 use tail packing 有一些罕见的文件系统配置,但这只有在第一个文件已经使用前一个文件的尾部块时才有帮助。

除非出现完美的场景,或者您的文件系统能够在文件中间标记部分块(我从未听说过),否则这是行不通的。只是为了解决边缘情况,除了更改内核接口来进行这样的调用之外,别无他法(回复:Link to a specific inode

我们可以让这比将两个文件的大小都翻倍更好吗?

是的,我们可以改用追加 (>>) 操作。

cat file2 >> file1

这仍然会导致两次使用file2 消耗的所有空间,直到我们可以将其删除。

我们可以避免使用额外的空间吗?

。除非有人带着我不知道的东西回来,否则你基本上不走运。可以 truncate 一个文件,忘记它的结尾的存在,但是没有办法忘记开头的存在,除非我们直接修改 inode 并不得不改变内核到文件系统的接口因为那绝对不是 POSIX 操作。

一次写一点,然后删掉我们写的怎么样?

再不行。由于我们无法切断文件的开头,因此我们必须重写从感兴趣点一直到文件结尾的所有内容。这对于 IO 来说是非常昂贵的,并且只有在我们已经读取了一半文件之后才有用。

稀疏文件呢?

也许吧! 稀疏文件允许我们存储一长串零,而不会占用几乎那么多空间。如果我们要从末尾开始大块读取file2,我们可以将这些块写入file1 的末尾。 file1 会立即看起来(和读取)好像它与两者的大小相同,但在我们完成之前它会被破坏,因为我们没有写入的所有内容都将充满零。

解释这一切本身就是另一个答案,但如果您可以进行备用分配,您将能够仅使用您的块读取大小 + 磁盘空间中的一点额外空间来执行此操作。有关文件中间稀疏块的参考,请参阅http://lwn.net/Articles/357767/ 或搜索涉及术语SEEK_HOLE

为什么这是“也许”而不是“是”?两部分:您必须编写自己的工具(至少我们在正确的站点上),并且文件系统和其他类似进程并不普遍尊重稀疏文件。幸运的是,您可能不必担心其他进程尊重您的文件,但您将不得不担心设置正确的标志并确保您的文件系统适合。最后,您仍将读取和重写file2 的长度,这不是您想要的。不过,这种方法确实意味着您可以附加少量磁盘空间,而不是使用至少 2*file2 的空间量。

【讨论】:

  • 这值得更多投票。
【解决方案2】:

你可以这样做

cat file2 >> file1

file1 将成为完整的内容。

【讨论】:

    【解决方案3】:

    不,不可能通过处理元数据来合并(在 Linux 上)两个大文件。

    也许您可以考虑为您的工作使用某种数据库。

    正如 Alexandre 所注意到的,您可以将一个大文件附加到另一个文件,但这仍然需要大量数据复制。

    【讨论】:

    • 理论上的方法是改变文件系统中的映射(文件>块)......也许有些文件系统有这种功能?
    • 不,他们没有,如果文件长度不是文件系统块大小的倍数,您的解决方案将不起作用。
    • 是的,我明白了,每个块的每个内容都需要移动以弥补差距。
    猜你喜欢
    • 2019-12-12
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2016-11-21
    相关资源
    最近更新 更多