目录
背景
像常见的Android 的linux平台,游戏,系统更新都会用到这一种方式。
以我自己的理解,这种方式有些像git中的版本管理, 以最少的时间进行版本管理.核心在于如何去记录文件的差异.
服务器端:
通过
bsdiff old new patchfile_path
生成差分文件.一般以.patch的文件命名.
客户端: 根据patch文件 通过
bspatch oldfile newfile patchfile_path
一般情况下,本以为可以直接通过压缩包的形式去进行, 安卓平台的.apk文件是可以的,单片机的可执行hex等格式的文件也是可以的. 但通过压缩的压缩包则可能会有隐患. 通过开会讨论以及本人查询资料发现 会因为压缩算法,压缩文件顺序的不一样而导致差分包出现问题.
原因有
主要原因有:
1. 不同的压缩算法会产生不同的压缩数据。即使原始数据相同,通过不同算法压缩结果也不完全一样。这会直接影响bsdiff的比较结果。
2. 即使使用同一压缩算法,压缩文件内原始数据的顺序改变也可能改变压缩效果。压缩算法利用重复模式来达到压缩效果。顺序改变会打乱这种模式。
3. bsdiff是按顺序比较数据生成差分的。所以就算压缩原理数据相同,其在压缩文件中的顺序变化也会导致bsdiff生成不同的差分补丁。
4. 压缩算法本身就利用了字典及顺序来提高压缩率。这与bsdiff的工作原理有一定冲突。综上,为了生成一致的bsdiff补丁,同一个数据生成压缩包时需要保证使用同一算法和稳定的顺序。否则差分结果可能会有较大变化。一般需要压缩数据再差分时,需要注意控制这两个因素,或者考虑在解压后对原始数据文件差分。
所以,考虑解压后保持相同的目录结构进行差分,即为生成的.patch文件和原工程有相同的目录.
所以需要写一个脚本,生成一个差分文件夹(目录),这个差分文件夹与原工程有相同的目录结构.
后面再根据这个差分文件夹进行升级,即为patch文件与原文件作用生成新文件,新目标和原目标相同.通过这种服务器上生成差分包,客户端上作用差分包的形式,差分包可以压缩,在客户端上解压缩,这样能更快更合理.
所以,总共需要有2个bash脚本,一个放服务器上,生成差分包.一个放客户端上,在收到差分包后进行本地升级.
内容
bsdiff和bspatch去官网上截至2023年10月27日没有下载源码的权限,所以得去别的地方找找源码.
准备工作
在windows平台上
参考
whistle713/bsdiff-win: bsdiff Windows binaries and Visual Studio 2015/2019 project. (github.com)
里面有提供能够在windows平台上允许的.exe可执行文件.
在linux平台上
参考
红橙Darren视频笔记 bsdiff bspatch 使用(Linux下)_洌冰的博客-优快云博客
完成编译
正式工作
这里需要考虑到旧的目标和新的目标的一些特殊情况.
- 新目标有新增文件的情况
- 新目标有删除原来旧文件的情况
- 新目标和旧目标的目录和文件都能对上,只是有变化.
- 旧目标和新目标有 大小为0 bytes 文件的情况(bsdiff失效)
相信一般的升级都会遇到 1.2.3.4所有情况,
对于第4种情况,不清楚是不是bsdiff的版本问题还是linux系统的问题,我在本地的liunx没有这个问题.
bsdiff在处理 大小为 0 bytes的文件时在linux上报错
报错
bsdiff:mmap() xxx:Invalid argument
思路:
对于第一种和第二种情况.
新目标新增: 在旧目标中生成一个相同名字的文件,不过大小为0 bytes
新目标有删除有原来旧文件的情况: 在新目标中生成一个相同名字的文件,大小依然为0bytes
这样的话,只要不出现 4 的这种问题都是能够通过bsdiff 生成相应的bspatch文件的.
生成差分文件思路
1.同步旧目标(对应新目标有文件增加时)
2.同步新目标(对应新目标删除了旧文件时)
3.递归遍历目标中的每一个文件,在另一个目标中进行查找, 可以直接通过bsdiiff 生成差分文件,
即使是两个相同的文件,也会生成patch文件,只不过bspatch 作用这个patch文件时并不会起作用,这样是非常方便了,都不需要进行判断了。这样表现为每一个文件都有对应的差分文件.

本文围绕Linux平台差分增量升级展开,介绍了生成和作用差分文件的思路,分析了压缩包用于差分可能出现的问题,给出在Windows和Linux平台的准备工作,还提及特殊情况处理、脚本编写及执行分析,最后修复了找不到软链接文件等bug。
最低0.47元/天 解锁文章
666





