Linux上大型文件的二进制差异/补丁?


13

我有两个分区映像(A和B),并希望使用它们创建一个补丁,我可以将其应用到另一台计算机上的A上,以便在不淹没网络的情况下获得新的B映像。我有以下要求:

  • 在Linux上工作
  • 可以创建差异
  • 可以使用差异来修补文件
  • 可以处理二进制文件
  • 可以处理大文件(几百GB应该可以工作)
  • 无需用户交互(只需一个控制台应用程序)
  • 理想情况下,应该能够读取/写入管道(以便我可以从gzip压缩文件中将其插入管道并写入其中)

是否存在类似的东西?


开始赏金时,我按Enter键的速度太快。这是我要添加的文本:
Basj

带有易于复制示例的答案rdiff对于将来的参考将是有价值的。示例:假设file1file2是两个相似的文件,每个文件大小均为1GB。1)如何计算rdiff?2)如何将这个rdiff保存到patch文件中?3)如何应用该patch文件file1进行恢复file2
巴吉

Answers:


13

您可能应该看一下与rsync相关的工具:rdiffrdiff-backup。该rdiff命令使您可以生成补丁文件并将其应用于其他文件。

rdiff-backup命令使用这种方法来处理整个目录,但是我猜您正在使用单文件磁盘映像,因此rdiff将成为一种使用。


1
rdiff的“签名”和“增量”是什么意思?手册页没有说。
Tor Klingberg

1
要回答我自己的问题,用rdiff创建增量是一个两步过程。首先从旧文件创建签名文件,然后使用签名和新文件创建增量。它们可以与rdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg

1
@TorKlingberg您可以举一个例子来发表新答案吗?假设file1file2是两个类似的文件,每个文件大小均为1GB。1)如何计算差异?2)如何将该差异保存到补丁文件中?3)如何应用该补丁文件file1进行恢复file2
Basj

7

xdelta可以做您想做的所有事情。合理的警告是,如果您的图像不太相似,则可能会得到一个很大的补丁,因为xdelta使用定义的内存缓冲区的一半来查找差异。可在TuningMemoryBudget Wiki页面上获得更多信息。增加缓冲区大小可能会有所帮助。

bsdiff是另一种选择,但是它非常占用 RAM,并且完全不适合任何磁盘映像大小的文件。

bsdiff非常消耗内存。它需要max(17*n,9*n+m)+O(1)内存的字节数,其中分别n是旧文件m的大小和新文件的大小。bspatch需要n+m+O(1)字节。


3

规范答案

关于rdiff的帖子,librsync 2.0.1 是对命令功能说明的不错的阅读方法,因此我在下面引用了该内容,以保留其他答案的内容。

重要的是,要设法更好地理解rdiff的三个步骤来更新文件:rdiff手册页上所讨论的签名deltapatch。我还在rdiffGitHub上找到了一个命令示例脚本,我将参考并引用该脚本示例。

实质上...

  1. 使用“开始”或基本文件[ file1],然后从中 创建签名文件
    • 这通常比基本/原始文件本身小得多
  2. 使用签名文件,您可以将其与file2与基本文件类似但又不同(例如,最近更新)的另一个文件[ ] 进行比较,并创建仅包含两个文件之间差异的增量文件
  3. 使用“仅差异”或增量文件,并将其与基本文件[ file1]进行比较,以生成一个新文件,其中包含与另一个文件[ file2]相匹配的更改。

快速命令(每个rdiff-example.sh

rdiff signature file1 signature-file            ## signature base file1
rdiff delta signature-file file2 delta-file     ## delta differences file2
rdiff patch file1 delta-file gen-file           ## compare delta to file1 to create matching file2

rdiff-example.sh

# $ rdiff --help
# Usage: rdiff [OPTIONS] signature [BASIS [SIGNATURE]]
#              [OPTIONS] delta SIGNATURE [NEWFILE [DELTA]]
#              [OPTIONS] patch BASIS [DELTA [NEWFILE]]

# Options:
#   -v, --verbose             Trace internal processing
#   -V, --version             Show program version
#   -?, --help                Show this help message
#   -s, --statistics          Show performance statistics
# Delta-encoding options:
#   -b, --block-size=BYTES    Signature block size
#   -S, --sum-size=BYTES      Set signature strength
#       --paranoia            Verify all rolling checksums
# IO options:
#   -I, --input-size=BYTES    Input buffer size
#   -O, --output-size=BYTES   Output buffer size

# create signature for old file
rdiff signature old-file signature-file
# create delta using signature file and new file
rdiff delta signature-file new-file delta-file
# generate new file using old file and delta
rdiff patch old-file delta-file gen-file
# test
diff -s gen-file new-file
# Files gen-file and new-file are identical

介绍

rdiff是一个用于计算和应用网络增量的程序。rdiff增量是二进制文件之间的增量,描述了如何自动编辑基础(或旧)文件以生成结果(或新)文件。

与大多数diff程序不同,librsync在计算diff时不需要访问两个文件。计算增量仅需要旧文件的简短“签名”和新文件的完整内容。签名包含旧文件块的校验和。使用这些校验和,rdiff在新文件中找到匹配的块,然后计算增量。

与xdelta或常规文本diff相比,rdiff增量通常不那么紧凑,并且生成速度也较慢。如果在计算增量时可能同时存在旧文件和新文件,则xdelta通常会生成小得多的文件。如果要比较的文件是纯文本,则GNU diff通常是一个更好的选择,因为该diff可以被人类查看并用作不精确的匹配项。

当不方便同时显示两个文件时,rdiff会变成自己的。这样的一个例子是两个文件位于不同的计算机上,而您只想传输差异。另一个示例是其中一个文件已移至存档或备份介质,仅保留其签名。

象征性地

signature(basis-file) -> sig-file

delta(sig-file, new-file) -> delta-file

patch(basis-file, delta-file) -> recreated-file

使用方式

rsync算法的典型应用是将文件A2从机器A传输到具有相似文件A1的机器B。可以按以下步骤完成:

  1. B生成A1的rdiff签名。称为S1。B将签名发送给A。(签名通常比它描述的文件小得多。)
  2. A计算S1和A2之间的rdiff增量。将此增量称为D。A将增量发送给B。
  3. B应用增量来重新创建A2。如果A1和A2包含相同字节的运行,则rdiff应该可以节省大量空间。

资源


1
非常感谢你!
Basj

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.