GeneralUpdate.Differential
命名空间: GeneralUpdate.Differential | 主要入口: IBinaryDiffer、BsdiffDiffer、StreamingHdiffDiffer | NuGet 包: GeneralUpdate.Differential
1. 组件简介
1.1 组件概述
GeneralUpdate.Differential 是 GeneralUpdate 的二进制差分组件,专注解决"一个旧文件 + 一个补丁文件 = 一个新文件"的问题。它提供可替换的文件级差分算法(BSDIFF 4.0 / Streaming HDiff)、补丁压缩抽象(BZip2 / Deflate,源码中预留 .NET 6+ Brotli)和 BSDIFF 兼容补丁读写能力。
目录级对比、批量补丁生成、并行调度、删除文件处理和更新流程编排由 GeneralUpdate.Core 的 DiffPipeline 或 GeneralUpdate.Tools 承担。
核心能力:
| 能力 | 说明 |
|---|---|
| 文件级差分生成 | CleanAsync(oldFile, newFile, patchFile) — 对比新旧文件生成 .patch 补丁 |
| 文件级差分应用 | DirtyAsync(oldFile, newFile, patchFile) — 旧文件 + 补丁 → 新文件 |
| 可替换差分算法 | BsdiffDiffer(BSDIFF 4.0,后缀排序)和 StreamingHdiffDiffer(块哈希索引) |
| 可替换压缩格式 | BZip2 (0x00)、Deflate (0x01),源码中通过 #if NET6_0_OR_GREATER 条件编译预留 Brotli (0x02) |
| BSDIFF 兼容格式 | 写入 33 字节扩展头(32 字节 BSDIFF40 + 1 字节压缩格式),兼容 32 字节旧头 |
| 线程安全 | 内置 differ 和压缩提供器均支持并发调用 |
解决的业务痛点:
- 全量更新带宽成本高,差分更新可将更新包从 GB 级降低到 MB 甚至 KB 级
- 不同文件类型和变化模式需要不同的差分策略(细粒度匹配 vs 快速块匹配)
- 压缩算法的选择影响客户端解压速度和补丁体积的平衡
大多数场景下你不需要直接调用 IBinaryDiffer。目录级差分、批量补丁生成、并行调度和更新流程编排由 GeneralUpdate.Core 的 DiffPipeline 或 GeneralUpdate.Tools 承担。Differential 只解决一个原子问题:一个旧文件 + 一个补丁文件 = 一个新文件。
业务使用场景:
- 大型桌面应用(多 DLL、资源文件)的增量更新
- 固件/驱动包的二进制差分分发
- 游戏资源热更新
- CI/CD 发布流水线中自动生成增量补丁包
1.2 环境与依赖
| 项目 | 说明 |
|---|---|
| 版本 | 10.5.0-beta.7 |
| 目标框架 | netstandard2.0(兼容 .NET Framework 4.6.1+ / .NET Core 2.0+ / .NET 5+) |
| 依赖包 | 无外部依赖(纯 .NET BCL) |
| 兼容性 | 所有支持 .NET Standard 2.0 的平台 |
2. 组件功能列表
| 功能名称 | 功能描述 | 类型 | 是否必填 | 备注限制 |
|---|---|---|---|---|
| BSDIFF 4.0 差分生成 | 基于后缀排序的经典差分算法,补丁体积稳定 | 基础 | 可选 | BsdiffDiffer,默认 BZip2 压缩 |
| BSDIFF 4.0 补丁应用 | 将 BSDIFF 格式补丁应用到旧文件 | 基础 | 可选 | 支持 32/33 字节两种头部格式 |
| Streaming HDiff 差分生成 | 基于 FNV-1a 块哈希索引的快速差分 | 基础 | 可选 | StreamingHdiffDiffer,默认 Deflate 压缩 |
| BZip2 压缩 | 补丁 控制段/差异段/额外段的 BZip2 压缩 | 基础 | 可选 | 格式字节 0x00,BsdiffDiffer 默认 |
| Deflate 压缩 | 补丁段的 Deflate 压缩,解压更快 | 基础 | 可选 | 格式字节 0x01,StreamingHdiffDiffer 默认 |
| 自定义差分算法 | 实现 IBinaryDiffer 接入自研算法 | 拓展 | 可选 | 需保证 Clean/Dirty 一致性 |
| 自定义压缩提供器 | 实现 ICompressionProvider 替换压缩方式 | 拓展 | 可选 | 新格式字节需配合扩展补丁读取逻辑 |
3. API 配置说明
3.1 配置字段(属性 Props)
Differential 本身是底层库,不提供配置类。所有参数通过构造函数传入。
BsdiffDiffer 构造参数:
| 字段名 | 数据类型 | 默认值 | 是否必填 | 枚举/取值范围 | 说明 |
|---|---|---|---|---|---|
compressionProvider | ICompressionProvider | BZip2CompressionProvider | 可选 | BZip2CompressionProvider / DeflateCompressionProvider | 补丁压缩提供器 |
StreamingHdiffDiffer 构造参数:
| 字段名 | 数据类型 | 默认值 | 是否必填 | 枚举/取值范围 | 说明 |
|---|---|---|---|---|---|
compressionProvider | ICompressionProvider | DeflateCompressionProvider | 可选 | BZip2CompressionProvider / DeflateCompressionProvider | 补丁压缩提供器 |
blockSize | int | 65536(64 KB) | 可选 | 正整数字节数 | 块大小,用于旧文件哈希索引 |
maxWindowSize | int | 134217728(128 MB) | 可选 | 正整数字节数 | 参与计算的最大内存窗口 |
DeflateCompressionProvider 构造参数:
| 字段名 | 数据类型 | 默认值 | 是否必填 | 枚举/取值范围 | 说明 |
|---|---|---|---|---|---|
optimalLevel | bool | true | 可选 | true / false | true = CompressionLevel.Optimal,false = CompressionLevel.Fastest |
ICompressionProvider 格式标识:
| Provider | 格式字节 | 可用性 | 说明 |
|---|---|---|---|
BZip2CompressionProvider | 0x00 | 完全可用 | BSDIFF 旧补丁兼容,解压成本较高 |
DeflateCompressionProvider | 0x01 | 完全可用 | 解压速度更友好,适合客户端批量应用 |
BrotliCompressionProvider | 0x02 | 仅 .NET 6+ 编译(源码中为完整实现,通过 #if NET6_0_OR_GREATER 条件编译) | 当前 netstandard2.0 包中不包含,生产不建议使用 |
3.2 实例方法
IBinaryDiffer:
| 方法名 | 入参明细 | 使用场景 | 注意事项 |
|---|---|---|---|
CleanAsync(string, string, string, CancellationToken) | oldFilePath — 旧文件路径;newFilePath — 新文件路径;patchFilePath — 补丁输出路径;cancellationToken | 发布/构建阶段生成补丁 | 大文件取消不会立即响应,需等待当前文件处理完成 |
DirtyAsync(string, string, string, CancellationToken) | oldFilePath — 旧文件路径;newFilePath — 补丁还原后文件输出路径;patchFilePath — 补丁文件路径;cancellationToken | 客户端升级阶段应用补丁 | 不会直接覆盖旧文件,结果写入 newFilePath |
3.3 回调事件
Differential 不发布事件。进度报告和事件通知由 Core 的 DiffPipeline 通过 DiffProgress 和 EventManager 实现。