`

用rdiff拆分合并文件

 
阅读更多

我们的一个方案是基于文件做多端数据同步,见另外一篇博客:基于文件的数据同步方案

其中的核心是如何正确、高效地同步文件,一开始我们使用了国产的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.8-1.el5.rf.x86_64 RPM包

    rdiff-backup-1.2.8RPM安装包

    rdiff:用于比较文件之间随时间的差异

    rdiff是用于比较一段时间内文件版本的软件包。 它是Rust编写的,期望版本> 1.17。 在法律允许的范围内,rdiff贡献者放弃了rdiff的所有版权以及相关或邻近的权利。 用法 在Cargo.toml : [ dependencies ] rdiff =...

    PyPI 官网下载 | rdiff_backup-1.9.1b0-cp37-cp37m-win32.whl

    `rdiff_backup` 是一个在PyPI上发布的Python库,它主要用于文件系统的备份和差异比较。这个资源的版本号为1.9.1b0,表明这是一个预发布版本,可能包含尚未在正式版本中验证的新功能或改进。 "cp37" 和 "cp37m" 是与...

    PyPI 官网下载 | rdiff_backup-2.0.4rc0-cp35-cp35m-manylinux1_i686.whl

    资源全名:rdiff_backup-2.0.4rc0-cp35-cp35m-manylinux1_i686.whl",这表明下载的文件是whl格式,whl是一种预先编译的Python二进制分发包,可以直接通过pip安装,无需编译源代码,这对于快速部署和使用Python库非常...

    WinMerge文件diff工具

    **WinMerge文件diff工具** WinMerge是一款在Windows操作系统下广泛使用的文件差异对比工具,它能够帮助用户快速识别并解决两个文件或目录之间的差异。这款工具以其直观易用的界面、强大的对比功能以及丰富的自定义...

    diff命令 比较文件的差异

    diff以逐行的方式,比较文本文件的异同处。如果指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录 。 语法格式:diff [参数] [目录] 常用参数: -a diff预设只会逐行比较文本文件 -...

    基于Diff算法的文本文件比对工具

    在这个基于Diff算法的文本文件比对工具中,使用了Java的Swing库来构建用户界面,Swing是Java提供的一个轻量级的图形用户界面工具包,可以创建功能丰富的跨平台应用。通过Swing,开发者可以创建出美观且易于操作的...

    diff命令 文件比较工具 文本比较工具 cygwin中的文本比较工具

    例如,`diff -r dir1 dir2`会递归地比较两个目录下的所有文件和子目录。这在版本控制中非常有用,可以帮助开发者了解更新后代码库的变动。 Cygwin是一个提供Linux兼容环境的Windows软件包,它包含了许多Unix工具,...

    rdiff-backup2attic

    由于Attic使用自己的备份格式,所以转换后无法直接回滚到rdiff-backup的任意时间点,但可以在Attic环境中恢复到相应的时间点。 5. 转换完成后,可以验证Attic存储库是否正确包含了所有原rdiff-backup的数据和元数据...

    bash-rdiff-backup

    5. **恢复数据**:当需要恢复文件时,可以使用 rdiff-backup 提供的命令来指定恢复的时间点。 总的来说,bash-rdiff-backup 是一种实用的备份解决方案,尤其适用于那些熟悉 Bash 和希望利用 rdiff-backup 特性的...

    ansible-role-rdiff-backup:在备份服务器上安装rdiff-backup并创建每日cron作业以提取备份

    《使用Ansible部署rdiff-backup与设置定时任务》 Ansible是一款强大的自动化运维工具,广泛应用于配置管理、应用部署和任务执行等场景。在这个场景中,我们将详细讲解如何使用Ansible来安装rdiff-backup,并配置...

    一个十分好用的hex文件编辑及diff工具

    标题中的“一个十分好用的hex文件编辑及diff工具”指的是该软件主要功能是用于编辑十六进制(hex)格式的文件以及进行差异比较(diff)。在计算机领域,hex编辑器是一种高级工具,允许用户查看和修改二进制文件的...

    SVN解决冲突(合并别人的修改)

    4. (r) resolved - 接受合并版本的文件。如果你已经手动解决了冲突,可以使用这个选项来告诉SVN冲突已经被解决。 5. (mf) mine-full - 接受整个文件的我方版本。忽略服务器上的更改。 6. (tf) theirs-full - 接受...

    Tatu-diff-merge:一个vscode并排的diff合并插件

    主要特点差异/与剪贴板合并差异/合并文件按键绑定打开“差异”窗口后,可以使用一些快捷方式。 ↓滚动并选择下一个差异↑滚动并选择上一个差异→合并选定的行Backspace删除选定的行Esc关闭差异窗口Shift +鼠标单击...

    文件比较算法剖析 DIff

    文件比较算法剖析 DIff 文件比较算法是计算机科学中的一种常见算法,用于比较两个文本文件的相似度和差异。在这篇文章中,我们将对文件比较算法进行剖析,并详细介绍其实现原理和算法思路。 文件比较算法的主要...

    node命令行生成补丁文件合并补丁生成新的文件

    2. 合并补丁生成新的文件:一旦有了一个或多个补丁文件,我们可以使用另一个命令将这些补丁应用到原始文件或目录上,生成一个更新后的版本。这在维护项目历史、集成多个人的工作或者在不丢失已有修改的情况下测试新...

    Python-WordGit一个工具允许您使用git来区分和合并Worddocx文件

    **Python-WordGit工具详解:使用Git管理Word docx文件** 在IT行业中,Git作为版本控制系统,被广泛用于管理代码和其他文本文件的变更历史。然而,由于Word文档(.docx格式)的特殊性,Git通常无法直接处理它们的...

    diff文件(夹)比对源码 c#

    `Diff.Net.exe`可能是该库的可执行程序,可以直接运行以进行文件比对,而`Diff.Net.docx`可能是其使用手册,包含了详细的使用指南和API参考。`License.txt`文件则包含了该软件的授权信息,确保合规使用。最后,`Diff...

    Qt5.9 文件比较工具

    对于两个文件的比较,Qt5.9的文件比较工具采用了经典的差异算法,如统一差异(Unified Diff)或上下文差异(Context Diff)。这些算法可以生成一个中间格式,展示两个文件的差异部分,以便用户理解变化。此外,Qt5.9...

    diff2 diff算法实践

    当发现两个文件中有相同或相似的块时,diff会输出一个补丁(patch)文件,记录下如何从一个文件转换到另一个文件的指令序列。这对于版本控制系统如Git和SVN至关重要,它们利用这种信息来跟踪和合并代码更改。 在...

Global site tag (gtag.js) - Google Analytics