使用基于差异的补丁方法更新我的程序

3 投票
2 回答
776 浏览
提问于 2025-04-16 01:05

目前我的程序通过下载最新的 .tar.gz 文件来更新自己,这个文件里包含了源代码,然后把它解压到程序所在的当前目录。更新有两种“模式”——一种是给运行 Python 源代码的用户,另一种是给以 Windows 可执行文件形式运行程序的用户。

随着时间的推移,我的程序文件大小在每次发布时都在变大,因为增加了新的图片、库、文档和代码。不过,有时候从一个版本到另一个版本只是代码发生了变化,这样用户就会不断重新下载所有的图片、文档等,尽管其实只是一些小的代码改动。

我在想,能否采用一种更有效的方法,使用补丁/差异(patch/diff)系统,让程序在更新时只下载小的变化部分,从一个版本逐步更新到另一个版本。

但是,我该怎么做呢?比如用户正在运行版本 0.38,而有 0.42 可用,他们需要下载 0.38->39;0.39->40;0.40->41,最后再到 0.41->42 吗?我该如何处理二进制文件的差异?(在我的情况下是图片)。

我还需要维护一个包含所有补丁的库,这也不是太麻烦。我只需在每次新发布时生成差异文件。但我想这对可执行文件来说比对纯 Python 代码要难一些,对吧?

任何建议都非常感谢。谢谢!

2 个回答

1

你的更新管理器可以知道当前应用程序的版本是什么,以及最新的版本是什么,并且只会应用相关的补丁。

假设用户现在使用的是0.38版本,而最新的版本是0.42。这个0.42的更新包含了0.39、0.40、0.41和0.42的补丁(可能还有更早的版本)。更新管理器会下载0.42的更新,它知道当前是0.38版本,所以会把所有相关的补丁都应用上。如果当前是0.41版本,它只会应用最新的补丁,依此类推。

3

我建议你不要自己重新发明一个更新管理系统,而是可以看看一些开源的选择,比如谷歌更新器(它在一年前就开源了,叫做Omaha)。我想你提到Windows,所以这个选择应该没问题,但如果你还需要支持Mac,类似的功能可以在更新引擎中找到(对于Linux,你可能更想使用特定发行版的包管理系统,而不是任何附加的系统)。

Omaha概述中,你会看到它的重点并不是专门在于确定和应用“增量更新”,而是为了用户的方便(以及当更新涉及安全问题时的安全性)来自动化这个过程。至于差异方面,我建议你可以参考版本控制系统,比如Subversion(实际上,你可以重用很多svn的代码)——只有文本文件会有差异,二进制文件的“差异”要么全有,要么全没有(对于大多数二进制文件格式来说,试图只发送部分更新的收益太小了;尤其是对于图像文件和各种压缩文件来说,底层内容的微小变化可能会导致最终文件的巨大变化)。

如果你觉得一些或所有的二进制文件可能真的能从使用差异和增量补丁的方式中受益,而不是逐个文件完全替换,我建议你先试试一个专门的工具,比如jojodiff来验证一下——如果确实是这样(也许只有某些文件适用,而其他文件则可以完全替换),你可以把补丁部分和更新器打包在一起(并通过Python等运行它作为子进程)。

至于在你的服务器上维护增量更新,混合的方法应该有效:也就是说,你会尝试保留所有的(数量呈平方增长的)更新(从A到A+1,A到A+2,A+1到A+2等等),但当增量更新的优势变得太小,以至于不值得占用服务器的存储空间和客户端的处理时间时,就“切断”每个分支(转而采用完全替换的方法)(当然,确定“太小”的阈值没有其他办法,只能依靠经验,也就是试试看)。

撰写回答