假设abc
我的本地计算机上有一个 4 GB 的文件。我已经通过 SFTP 将它上传到远程服务器,花了几个小时。
现在我在本地稍微修改了文件(可能最大 50 MB,但不是此文件中的连续字节),并将其保存到abc2
. 我还将原始文件保存在abc
本地计算机上。
如何计算abc
和的二进制差异abc2
?
应用:
我只能将
patch
文件(可能最大 100MB)发送到远程服务器,而不是重新上传整个abc2
文件(再次需要几个小时!),并且仅abc2
在远程服务器上重新创建。abc
patch
在本地,我可以只保存+ ,而不是浪费 8 GB 来备份
abc
和,所以它只需要 < 4100 MB。abc2
abc
patch
这个怎么做?
PS:对于文本,我知道diff
,但在这里我正在寻找适用于任何原始二进制格式的东西,它可以是 zip 文件或可执行文件,甚至是其他类型的文件。
PS2:如果可能,我不想使用rsync
; 我知道它可以以有效的方式在两台计算机之间复制更改(而不是重新发送未更改的数据),但是在这里我真的想要一个patch
文件,如果我同时拥有abc
和patch
.
对于第二个应用程序/问题,我会使用类似
restic
or的重复数据删除备份程序borgbackup
,而不是尝试手动跟踪“补丁”或差异。restic
备份程序允许您将目录从多台机器备份到同一个备份存储库,在单个机器的文件片段之间以及机器之间对备份数据进行重复数据删除。(我没有使用 的用户经验borgbackup
,所以我对该程序无话可说。)计算和存储
abc
和abc2
文件的差异可以用rsync
.这是一个153 MB
abc
的示例。abc2
该文件abc2
已通过使用其他一些数据覆盖文件的前 2.3 MB 进行了修改:我们创建了用于转换的补丁
abc
并将abc2
其命名为abc-diff
:生成的文件
abc-diff
是实际的差异(您的“补丁文件”),同时是为您创建abc-diff.sh
的简短 shell 脚本:rsync
给定文件,此脚本会进行修改
abc
,使其变得与 相同:abc2
abc-diff
该文件
abc-diff
现在可以转移到您拥有的任何其他地方abc
。使用该命令rsync --read-batch=abc-diff abc
,您可以将补丁应用于文件,将其内容转换为与您创建差异的系统上abc
的文件相同。abc2
第二次重新应用补丁似乎是安全的。没有错误消息,文件内容也没有改变(MD5 校验和没有改变)。
请注意,除非您创建明确的“反向补丁”,否则无法轻松撤消补丁的应用。
我还测试了将 2.3 MB 的修改写入数据中的其他位置,稍
abc2
远一点(大约 50 MB),以及在开始时。生成的“补丁”大小为 4.6 MB,这表明补丁中仅存储了修改后的位。使用bsdiff/bspatch或 xdelta 等。
但是,需要注意手册页中的这些警告:
bsdiff
使用的内存等于 oldfile 大小的 17 倍,并且需要绝对最小工作集大小为oldfile大小的 8 倍。bspatch
使用的内存等于oldfile的大小加上newfile的大小,但可以容忍非常小的工作集而不会显着降低性能。您是否尝试过强制
diff
将文件视为文本:正如这里所解释的。
-u
输出NUM(默认3)行统一上下文-a
将所有文件视为文本这应该会给你一个补丁。这样做的缺点是“线条”可能会很长,并且可能会使补丁膨胀。
使用xdelta,它正是为这种用途而创建的。基于最新版本的 VCDIFF (RFC 3284)。
根据我的测试补充其他答案:
和
diff
我创建了两个非常相似的 256 MB 文件
abc
和abc2
. 然后让我们创建差异文件:现在让我们尝试恢复
abc2
原始abc
文件和abc-abc2.diff
:或者
或者
它适用于 Linux。我也在 Windows 上尝试过(patch.exe 和 diff.exe 也可用),但由于未知原因它失败了:生成的
abc3
文件只有 1KB 而不是 256MB(我稍后会在这里更新这个答案)。和
rsync
如已接受的答案中所述,此方法有效:
和
rdiff
如this answer详述,这也是一个解决方案:
还在 Windows 上使用 rdiff.exe 进行了测试,并且可以正常工作。