我们的一个方案是基于文件做多端数据同步,见另外一篇博客:基于文件的数据同步方案
其中的核心是如何正确、高效地同步文件,一开始我们使用了国产的libsync库:libsync
基本的流程是:有文件A和B,现在想把文件A“变成”文件B,先对文件A做chunk;然后用chunk和文件B对比,得到delta;最后用文件A和delta做sync操作,A就变成了B的复制。但是实际测试之后发现,在某些场景下,合并得到的文件和原始文件的MD5不一致,说明在过程中,文件已经损坏了
看源代码,没有找到原因。于是直接改用另一个更有名的库,librsync,地址在:librsync。编译之后会得到2个东西,一个是可执行命令行rdiff,另一个是静态链接库librsync.a,如果需要动态链接库比如.so或.dylib,可能需要自己改一下Makefile
经过测试,刚才合并出错的2个文件,用rdiff命令执行signature -> delta -> patch之后,MD5完全一致,说明新的库本身是OK的,没有遇到老库的bug。那么接下来还需要做2件事:
1、将librsync库集成到iOS APP里
2、将librsync库集成到server代码里
集成进ios平台
我在MBP上没有办法跑完make,因为始终少popt.h这个头文件,找了很久也没有找到MAC平台下能用的popt-devel包。倒是在CentOS上直接yum install popt-devel就搞定了。所以我的librsync.a链接库是在linux下编译出来的,直接放到iOS APP里估计也用不了。反正有源代码,我干脆把相关的.c和.h放到工程里了,随APP一起编译,稍微改了改就编译通过了
调用的代码也很简单,因为在客户端只需要delta,我就只包装了一个函数:
-(int) deltaWithSignature:(NSString*)signaturePath newFilePath:(NSString*)newFilePath deltaPath:(NSString*)deltaPath
{
rs_signature_t *sumset;
rs_stats_t stats;
FILE *sig_file = rs_file_open([signaturePath UTF8String], [@"rb" UTF8String]);
FILE *new_file = rs_file_open([newFilePath UTF8String], [@"rb" UTF8String]);
FILE *delta_file = rs_file_open([deltaPath UTF8String], [@"wb" UTF8String]);
rs_result result = rs_loadsig_file(sig_file, &sumset, &stats);// 读取chunk文件
if (result != RS_DONE){
return result;
}
if ((result = rs_build_hash_table(sumset)) != RS_DONE){
return result;
}
result = rs_delta_file(sumset, new_file, delta_file, &stats);
rs_free_sumset(sumset);
rs_file_close(delta_file);
rs_file_close(new_file);
rs_file_close(sig_file);
return result;
}
集成进server端代码
官方自带的Makefile只能打出静态链接库,如果要打出所需的.so文件,还需要自己改一下Makefile。而且我们这个服务是用node写的,就算得到了.so,还是需要用FFI再重新包装一下,才能在node里面调用,同样很费事
所以最后我是在环境里编译好了rdiff命令行,然后代码里直接调用,省去了封装FFI的麻烦。由于是异步调用,性能也没有太大的问题,不过不太好的就是调用过程中的精细控制不好实现,另外集群部署的时候也会麻烦一点
var cmd = "rdiff patch " + localRdbPath + " " + uploadPath + " " + syncPath;
console.log(cmd);
exec(cmd, {}, function (err, stdout, stderr) {
// logic
});
分享到:
相关推荐
rdiff-backup-1.2.8RPM安装包
rdiff是用于比较一段时间内文件版本的软件包。 它是Rust编写的,期望版本> 1.17。 在法律允许的范围内,rdiff贡献者放弃了rdiff的所有版权以及相关或邻近的权利。 用法 在Cargo.toml : [ dependencies ] rdiff =...
基于Diff算法的文件比对工具,使用Swing制作的界面。分享给朋友们参考 比对结果只是简单的输出日志,之前用于公司的Python代码对比分析。
diff以逐行的方式,比较文本文件的异同处。如果指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录 。 语法格式:diff [参数] [目录] 常用参数: -a diff预设只会逐行比较文本文件 -...
WinMerge,文件diff工具,可以在windows系统下比较两个文件的区别
主要特点差异/与剪贴板合并差异/合并文件按键绑定打开“差异”窗口后,可以使用一些快捷方式。 ↓滚动并选择下一个差异↑滚动并选择上一个差异→合并选定的行Backspace删除选定的行Esc关闭差异窗口Shift +鼠标单击...
资源来自pypi官网。 资源全名:rdiff_backup-1.9.1b0-cp37-cp37m-win32.whl
资源来自pypi官网。 资源全名:rdiff_backup-2.0.4rc0-cp35-cp35m-manylinux1_i686.whl
Go的diff3文本合并实现基于以下很棒的论文。 Diff3基于下面的很棒的论文,Go中的diff3文本合并实现。 Sanjeev Khanna,Keshav Kunal和Benjamin C.撰写的“ Diff3的形式调查”。Pierce用法import“ github....
rdiff-backup2attic 将rdiff-backup存储库转换为阁楼存储库。 用法 rdiff-backup2attic <rdiff> 执照
diff命令,可以比较两个文件是否相同,可以比较两个文本文件的差异。 是从cygwin中分离出来的,可以在您的程序中调用它。
国外一款diff工具,简洁的英文界面。可比较两个文件夹的异同、两个文件的异同,适用于代码版本比较以及文件备份时的查缺补漏
diff A B >C ,一般A是原始文件,B是修改后的文件,C称为A的补丁文件。 patch A C 就能得到B, 这一步叫做对A打上了B的名字为C的补丁。 patch -R B C 就可以重新还原到A了。 2) 内核补丁 生成 diff -uNr ...
ansible-role-rdiff-backup 在备份服务器上安装rdiff-backup并创建每日cron作业以提取备份
Java Diff / Merge工具是用于为Java文件上的合并冲突提供信息和自动解决方案的实用程序。 跑步 该项目正在积极开发中,但尚未准备好使用... 目标 仅使用此工具在我们的生产环境中执行合并 变更日志 v0.1(2012-10-22...
文件比较算法的分析资料,中文文件比较算法的分析资料,中文文件比较算法的分析资料,中文文件比较算法的分析资料,中文文件比较算法的分析资料,中文
介绍java-object-diff是一个简单但功能强大的库,用于查找Java对象之间的差异。 它需要两个对象并生成一个树形结构,该结构表示对象及其子对象之间的任何差异。 然后可以遍历此树以提取更多信息或将更改应用于基础...
这是java的diffutils工具,很不错。根据它可以做出和svn或其他的文件比较一样的效果。