如何合并2个大文件

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

cat file1 file2> final_file

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

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

只有在模糊的理论 。 由于磁盘存储总是基于块和文件系统,因此将块存储在块边界上,如果第一个文件在块边界上完美结束,则只能将一个文件附加到另一个文件而不需要重写。 有一些罕见的使用尾部打包的文件系统配置,但只有在已经使用前一个文件的尾部块的第一个文件时才有所帮助。

除非出现这种完美的情况,否则你的文件系统能够在文件中间标记一个部分块(我从来没有听说过这个),这是行不通的。 只是为了解决边缘情况,除了改变内核接口来做这样的调用之外,也没有办法(re: 链接到特定的inode )

我们可以做得更好比两个文件的大小加倍吗?

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

 cat file2 >> file1 

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

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

没有 。 除非有人回来,我不知道,你基本上运气不好。 可能会截断一个文件,忘记它的结尾是否存在,但是除非我们直接修改inode并不得不将内核接口更改为文件系统,否则就无法忘记这个start的存在。绝对不是一个POSIX操作。

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

再没有 由于我们不能将文件的开始截断,所以我们不得不重写从感兴趣点到文件结尾的所有内容。 这将是非常昂贵的IO,只有在我们已经读了一半的文件后才有用。

什么稀疏文件?

也许! 稀疏文件允许我们存储一长串零,而不用占用太多的空间。 如果我们从最后开始以大块的形式读取file2 ,我们可以将这些块写到file1的末尾。 file1会立即看起来(和读取),就好像它们的大小一样,但是在完成之前它会被破坏,因为我们没有写的东西都会被填满。

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

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

你可以这样做

 cat file2 >> file1 

file1将成为完整的内容。

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

也许你可能会为你的工作考虑某种数据库。

正如亚历山大注意到的,你可以附加一个大文件到另一个,但是这仍然需要大量的数据复制。