不同平台下生成patch差分包
增量更新算法官网
bspatch
http://www.daemonology.net/bsdiff/
bzip2
http://www.bzip.org/downloads.html
一、增量更新原理
在计算机世界,所有的文件都可以用二进制来表示。增量更新通过哈夫曼算法将新旧文件对比,生成一个差分包(经过压缩)。旧的文件通过与差分包解压后进行合并即可得到新的文件。
哈夫曼算法
比较两个文件,若文件相同只保存索引,若文件不同则保持索引和内容
二、Windows平台差分工具
下载bsdiff,可以通过官网下载,也可以通过以下链接下载
https://download.csdn.net/download/cx1229/10844285
解压之后,Release文件夹下已经提供了.exe可执行文件,可以直接用命令提示符来生成差分包。
用法:使用CMD输入
bsdiff.exe oldfile newfile patchfile
使用Visual Studio来生成差分工具。
新建一个C++空项目,将所有的c、cpp和h文件拷贝进去,这里我创建了一个include的文件夹用来放置头文件,还有一个src文件夹用来放置源文件。运行之后即可生成.exe差分工具。
生成.dll动态链接库供java调用
注意:需将 VS 解决方案配置 改成X64
一、创建一个java工程,创建一个BsdiffUtils,写一个native方法
public native static void bsdiff(String oldFilePath, String newFilePath, String patchFilePath);
二、使用javah生成头文件,并将此头文件和jni.h、jni_md.h一并复制到VS工程中,将bsdiff.cpp中的main方法改名为bsdiff
三、创建一个.c源文件并实现java头文件中的方法
#include <com_chauncey_bsdiff_BsdiffUtils.h>
#include <bzlib.h>
JNIEXPORT void JNICALL Java_com_chauncey_bsdiff_BsdiffUtils_bsdiff
(JNIEnv * env, jclass jclz, jstring jst_oldPath, jstring jst_newPath, jstring jst_patchPath){
int agrc = 4;
char* oldPath = (*env)->GetStringUTFChars(env, jst_oldPath, NULL);
char* newPath = (*env)->GetStringUTFChars(env, jst_newPath, NULL);
char* patchPath = (*env)->GetStringUTFChars(env, jst_patchPath, NULL);
char* argv[4];
argv[0] = "random"; //任意字符,查看原方法可知第一个参数无实际作用
argv[1] = oldPath;
argv[2] = newPath;
argv[3] = patchPath;
bsdiff(agrc, argv);
(*env)->ReleaseStringUTFChars(env, jst_oldPath, oldPath);
(*env)->ReleaseStringUTFChars(env, jst_newPath, newPath);
(*env)->ReleaseStringUTFChars(env, jst_patchPath, patchPath);
}
四、生成.dll动态链接库,放入java工程,通过
System.loadLibrary
即可调用native方法
使用Visual Studio时可能会出现的坑
打开bsdiff.cpp发现#include "bzlib.h"
找不到了
有两种解决方法:
- 改成
#include "../include/bzlib.h"
- 项目右键 --> 属性 --> C/C++ --> 附加包目录 。把自己创建的文件夹添加进去
运行报 _CRT_SECURE_NO_WARNINGS
有两种解决办法:
- 在文件加入
#define _CRT_SECURE_NO_WARNINGS;
- 项目右键 --> 属性 --> C/C++ --> 命令行 --> 其它选项 --> 输入
-D _CRT_SECURE_NO_WARNINGS
报错误 error C4996: 'setmode': The POSIX ...
:
项目右键 --> 属性 --> C/C++ --> 常规 --> SDL检查 --> 否
报错误 error C2664: “DWORD FormatMessageW...
解决方案:项目右键 --> 属性–> 常规 --> 字符集 > 多字节字符集
三、Linux平台差分工具
- 创建一个src文件夹,将 bsdiff-4.3 中的 bsdiff.c 和 bzip2 中所有的 .c和.h 等一共16个文件全部拷贝进去。
- 打开除了 bsdiff.cpp 所有 .c 文件并修改 main 方法名为 文件名_main(main方法入口只能有一个)。
- 打开除了 bsdiff.c 修改 <bzlib.h> 为 “bzlib.h”(否则会导致找不到)
- 并将此文件夹放到 Linux 平台中。
通过命令行进入src文件夹中并赋予所有文件读写权限
chmod -R 777 ./*
- 通过 gcc 将其中一些 .c 文件编译为可执行文件,gcc在Linux中已经集成了,如果要编译成Android可用的so文件,则需要安装NDK交叉编译工具链
gcc -fPIC blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c bzlib.c crctable.c -o ChaunceyBsDiff
-o ChaunceyBsDiff
表示要生成的可执行文件
- 执行
./ChaunceyBsDiff old.apk new.apk apk.patch
生成差分文件