一:“压缩率”和“速度”是相对等级,不是跨平台固定数值;设备端表现必须以 ESP-IDF 构建和真机数据为准。
| 算法 | 压缩率 | 压缩 / 解压速度 | 设备端 RAM | 代码体积 | 生态与格式 | 本项目判断 |
|---|---|---|---|---|---|---|
| LZ4 Frame | 中低 | 极快 / 快 | 低;通常需 64 KiB 级历史窗口,可配置独立块 | 中等 | 成熟,桌面端与 C 端都易接入 | 首选 |
| Heatshrink | 中低至中 | 较慢 / 较慢 | 极低;窗口可缩到数百字节至数 KiB | 很小 | 嵌入式友好,但桌面工具和归档生态较弱 | 极低内存备选 |
| DEFLATE / gzip | 中 | 中慢 / 中 | 中;典型 32 KiB 窗口外加状态 | 中等 | 最通用,几乎所有平台都有 | 兼容性备选 |
| Zstandard | 高 | 快 / 很快 | 中高;取决于窗口,常见配置明显高于 LZ4 | 较大 | 优秀,支持字典、校验和丰富参数 | 资源充足时升级项 |
| Snappy | 低 | 极快 / 极快 | 低至中 | 中等 | 库成熟,但标准文件格式与工具链不如 LZ4 | 没有明显优势 |
| Brotli | 高 | 慢 / 中 | 高 | 大 | Web 生态强,嵌入式文件传输生态一般 | 不建议 |
| LZMA2 / xz | 很高 | 很慢 / 慢 | 很高 | 大 | 桌面归档成熟 | 不适合实时设备端 |
逐项判断
LZ4 Frame
Frame 格式自带长度、块边界和可选内容校验,比裸 LZ4 Block 更适合协议传输。建议使用 64 KiB block、独立块模式, 设备以小输入/输出缓冲循环处理;独立块会略降压缩率,但状态更简单。
Heatshrink
最大价值是窗口和 lookahead 可编译期控制。如果 Classic ESP32 的可用内存无法承受 LZ4 实测需求,它是可靠退路, 但不应仅凭“嵌入式专用”就默认选择。
DEFLATE / gzip
最大优势是兼容性。缺点是设备压缩端 CPU 成本偏高;双向实时压缩时可能拖慢下载生成。若要求用户无需专用工具即可解压, gzip 才有明显产品价值。
Zstandard
综合压缩率和桌面速度优秀,但解码内存由 frame window 决定,不能接受任意外部 zstd 文件。若未来支持,协议必须限制最大 window, 并拒绝超出设备能力的 frame。
Brotli 与 LZMA2
更适合离线分发,不适合设备边读边压缩下载。它们增加 CPU、RAM、代码体积和超时风险,节省的字节未必能抵消工程复杂度。
Snappy
性能定位与 LZ4 接近,但文件格式、命令行工具和嵌入式采用面没有形成足以替代 LZ4 的优势,因此无需首版同时支持。
二:归档格式与协议承载
| 组合 | 适用对象 | 流式特性 | 实现复杂度 | 建议用途 |
|---|---|---|---|---|
| 单文件 + LZ4 Frame | 单文件 | 天然流式;头部即可开始解压 | 简单 | 单文件上传、OTA |
| TAR + LZ4 Frame | 文件夹 | 天然顺序打包/解包,无需尾部索引 | 简单 | 文件夹双向传输首选 |
| ZIP | 文件/文件夹 | 中心目录通常在尾部;流式生成、恢复和统一校验更复杂 | 中高 | 强调桌面直接打开时 |
| Zstd tar | 文件夹 | 流式良好,但设备端内存与代码体积更高 | 中 | 后续高压缩率档位 |
| 自定义分块容器 | 任意 | 可做块校验、索引和断点恢复 | 高 | 未来确实需要压缩流断点续传时 |
协议不应只保存一个 compression 字段
algorithm:NONE / LZ4_FRAME,预留 ZSTD、HEATSHRINK。
archive:NONE / TAR。
mode:STORE、DECOMPRESS、EXTRACT、COMPRESS、ARCHIVE_COMPRESS。
wire_size:HFT 实际接收或发送的字节数。
original_size:解压后的总字节数,用于容量和压缩炸弹限制。
wire_sha256:压缩流或存储包的完整性。
content_sha256:还原后单文件内容;文件夹使用 manifest 哈希。
max_files、max_depth:限制归档规模。
overwrite_policy:拒绝、替换或原子提交。
frame_window:未来支持 Zstd 时必须参与能力校验。
..、路径穿越、符号链接、硬链接、重复目标路径、超长名称以及设备文件类型。 先写临时目录,所有文件与 manifest 校验成功后再提交;失败或断连必须清理临时内容。为什么不首选 ZIP
ZIP 对桌面用户很友好,但目录信息、每文件压缩方式、数据描述符和尾部中心目录会扩大解析状态机。 当前目标是设备端稳定的顺序流,TAR 只需要依次读取 header 和 payload,更适合 LittleFS、SD 卡和 PSRAM Backend。 如果产品明确要求“传下来的包可被系统文件管理器直接打开”,再增加 ZIP 的“仅保存”模式即可,无需设备端首版解包 ZIP。
三:按场景选择:
| 场景 | 推荐格式/流程 | 关键说明 |
|---|---|---|
| OTA 压缩上传 | 签名后的完整 .ota 再套 LZ4 Frame | 设备先解压,再交给现有 OTA Backend;签名仍覆盖原始 HOTA 数据 |
| 普通单文件上传并还原 | LZ4 Frame 流式解压 | 不保存压缩包;写临时文件,原始 SHA-256 通过后提交 |
| 文件夹上传并还原 | TAR + LZ4 Frame 流式解包 | 限制路径、文件数、目录深度和解压后总大小 |
| 上传但保留压缩包 | 原样保存 .lz4 / .tar.lz4 | HFT 不解压,仅校验传输数据与压缩包哈希 |
| 单文件压缩下载 | Backend → LZ4 Frame → HFT | 设备实时压缩,不必先生成中间文件 |
| 文件夹压缩下载 | Backend → TAR → LZ4 Frame → HFT | 先输出 TAR 元数据,再顺序读文件并压缩 |
| 已压缩媒体或归档 | RAW 或 AUTO 跳过压缩 | PNG/JPEG/MP4/ZIP 等通常收益很低,继续压缩可能变大 |
| 极小文件 | RAW | 压缩头和协商开销可能超过节省量 |
AUTO 模式建议:
1. 小于可配置阈值的文件直接 RAW,避免 frame 头和初始化开销。
2. 对输入前若干 KiB 试压缩;收益低于阈值时切回 RAW,并在 OPEN 响应中返回实际模式。
3. 识别 PNG、JPEG、MP4、ZIP、gzip、LZ4、Zstd 等格式,默认不重复压缩,但允许用户强制。
4. 文件夹总是先 TAR;是否再 LZ4 由试压缩和用户策略决定。
5. 设备不能擅自把 STORE 改成 EXTRACT,或把 EXTRACT 改成 STORE;只有请求端选择 AUTO 时才能自动决策。
