如何让7z仅压缩文件更新部分?求替代压缩方案
问题分析
首先得明确:7z(尤其是默认的LZMA/LZMA2压缩算法)本身不支持单文件的增量压缩,这是由它的压缩原理决定的。LZMA是基于滑动窗口的字典压缩算法,它需要整个文件的上下文来生成最优的压缩结果——哪怕你只是在文件末尾追加了几个字节,它也无法复用之前已压缩的1GB数据,必须重新处理整个文件才能维持压缩率。7z u命令的更新操作,本质上是把归档里的旧文件替换成新的完整压缩版本,所以耗时和第一次压缩差不多。
用7z模拟增量压缩(手动分块法)
如果你一定要用7z实现近似的增量压缩效果,可以通过手动分块的方式模拟,不过操作会比较繁琐:
- 首次分块并压缩:把大文件分割成固定大小的小块,再压缩所有块:
# 分割1GB文件为100MB的小块,自动生成aa、ab...后缀的分块文件 split -b 100M target/temp_1GB_file target/temp_1GB_file.part # 将所有分块压缩到归档 7z a target.7z target/temp_1GB_file.part*
- 追加内容后更新归档:只处理新增的部分或者修改的最后一块:
# 记录追加前的文件大小 original_size=$(stat -c%s target/temp_1GB_file) # 追加内容到文件 echo 'hello' >> target/temp_1GB_file # 提取新增的字节到新分块 dd if=target/temp_1GB_file of=target/temp_1GB_file.part_new skip=$original_size bs=1 # 将新分块加入归档 7z u target.7z target/temp_1GB_file.part_new
解压时需要把所有分块合并:cat target/temp_1GB_file.part* > target/temp_1GB_file
更高效的替代方案
手动分块不够优雅,推荐这些专门支持增量压缩/备份的工具:
tar 增量备份:tar原生支持增量模式,通过快照文件记录文件状态,只备份变化的部分,配合gzip/xz压缩即可:
# 第一次全量备份(生成快照文件tar_snapshot.file,用于后续增量对比) tar --create --listed-incremental=tar_snapshot.file --gzip --file=full_backup.tar.gz target/ # 追加内容后的增量备份(复用快照文件,只备份变化部分) tar --create --listed-incremental=tar_snapshot.file --gzip --file=incremental_backup.tar.gz target/恢复时先解压全量备份,再依次解压增量备份即可。
rsync + 压缩:用rsync生成文件差异补丁,再压缩补丁,适合跨机器备份场景:
# 首次全量压缩备份 7z a full_backup.7z target/temp_1GB_file # 生成增量补丁(patch是补丁文件的前缀,会生成patch和patch.sh两个文件) rsync -av --only-write-batch=patch target/temp_1GB_file full_backup/ # 压缩补丁文件 7z a incremental_patch.7z patch* # 恢复时:先解压全量备份,再应用补丁 rsync -av --read-batch=patch target/temp_1GB_filezstd 补丁压缩:zstd是现代高效压缩工具,支持基于已有压缩文件生成增量补丁,适合单文件的增量更新(需要zstd 1.4.0+版本):
# 首次压缩文件 zstd -o full.zst target/temp_1GB_file # 追加内容后,生成增量补丁 zstd -o incremental.zst --patch-from=full.zst target/temp_1GB_file # 恢复时:解压全量文件并应用补丁 zstd -d full.zst --patch-from=incremental.zst -o restored_filebup:专为大文件增量备份设计的工具,基于Git的对象存储,能高效识别文件的重复和修改部分,适合频繁更新的大文件场景。
内容的提问来源于stack exchange,提问作者alper
相关产品推荐
相关产品推荐

