文件粒度的差分文件生成

最近接了个任务,让公司某个App内置的资源文件支持增量升级.(Android/iOS,之前更新资源文件都是下载完整包全量更新)

Goolge了下解决方法,业内普遍的做法是:

1.Google Play与App Store都支持App的增量更新;

2.对于不上架官方市场,又想提供增量更新的App:

Android解决方法:

https://my.oschina.net/liucundong/blog/160436

iOS解决方法:

https://www.jianshu.com/p/3c58760079d9

总结下来,主要是用到了两个库:

bsdiff: https://link.jianshu.com/?t=http://www.daemonology.net/bsdiff/

bzip2: http://www.bzip.org/downloads.html

三个步骤(以Android App):

1.在服务器端,生成新版本apk与旧版本apk的差分包(使用bsdiff算法);
2.在手机客户端,使用已安装的旧版apk与这个差分包,合成为一个新版apk(使用bspatch算法);
3.校验新合成的apk文件是否完成,签名时候和已安装客户端一致,如一致,提示用户安装;

Android与iOS的区别在于Android可以根据apk的增量更新包更新App本身及内置资源文件,iOS则只能根据资源文件的增量包更新内置资源文件.

上述方法的差分文件粒度是字节级别的,考虑到公司现有的资源文件更新机制,将步骤1制作的差分文件粒度修改为文件级别更为合适,搜索了一圈,找到一个Linux下较为合适的解决方案:

https://my.oschina.net/mengshuai/blog/551379

主要用到了rsync命令:

完整的shell代码为:

rsync --dry-run -crnC --out-format="%n"  newVersion/  oldVersion/ | grep -v "/$" | xargs -I{} rsync -vR newVersion/./{} patch/

总体思路是先列出差异文件,然后复制到补丁目录:

1.列出差异文件

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。

-v 详细模式输出

-c 根据checksum结果过滤文件,而非文件大小和修改时间;

-r 递归地(否则不处理子目录下的文件)

-n 干跑(不对目录造成任何实际影响)

-C 使用和CVS一样的方法自动忽略文件

--out-format 指定要输出要更新的文件信息的格式, 使用%n可以列出newVersion下所有与oldVersion不同的文件的相对路径

注:使用 man rsyncd.conf 可以查看格式:

%b the number of bytes actually transferred

%B the permission bits of the file (e.g. rwxrwxrwt)

%c the total size of the block checksums received for the basis file (only when sending)

%C the full-file MD5 checksum if --checksum is enabled or a file was transferred (only for protocol 30 or
     above).

%f the filename (long form on sender; no trailing "/")

%G the gid of the file (decimal) or "DEFAULT"

%h the remote host name (only available for a daemon)

%i an itemized list of what is being updated

%l the length of the file in bytes

%L the string " -> SYMLINK", " => HARDLINK", or "" (where SYMLINK or HARDLINK is a filename)

%m the module name

%M the last-modified time of the file

%n the filename (short form; trailing "/" on dir)

%o the operation, which is "send", "recv", or "del." (the latter includes the trailing period)

%p the process ID of this rsync session

%P the module path

%t the current date time

%u the authenticated username or an empty string

%U the uid of the file (decimal)

https://superuser.com/questions/1259494/whats-the-difference-between-n-and-f-in-rsyncs-out-format

grep -v "/$" : grep -v表示反向过滤,"/$"匹配以/结尾的字符串,二者结合则可以过滤掉目录,只显示增量文件路径.

于是下述命令即可将增量文件全部列出来:

rsync --dry-run -crnC --out-format="%n"  newVersion/  oldVersion/ | grep -v "/$"

2.复制到补丁目录:

之后将增量文件全部复制到补丁文件夹即可:

此处仍然采用rsync命令,使用 xargs接受上面的输出传递给rsync:

xargs -I{} rsync -vR newVersion/./{} patch/

xargs -I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉

rsync -R 使用相对路径.

注意.经过测试,如果命令写成:

xargs -I{} rsync -vR newVersion/{} patch/

则patch目录下是newVersion目录,newVersion下才是差分文件.

 

 

 

 

你可能感兴趣的:(Linux)