1608 字
8 分钟

SFC:基于自定义 .sy 格式的文件归档工具

项目仓库: Gitee | GitHub

SFC(Simple Files Compressor)面向 Windows,输出自定义 .sy 格式。核心链路基于 C++ 实现文件头、目录块、数据块、Huffman 压缩与 AES 加密,外层以 Qt GUI 作为主要交互入口。压缩与解压都跑在专职读线程、N 个计算工人、专职写线程的三段流水线上;编码用平坦符号表加 64 位位缓冲,解码用 canonical 码加 12 位查表,加密走 Windows CNG 的标准 AES-128-CTR。13.47 GiB / 45,390 个文件的真实数据上,整体吞吐压缩 254.3 MiB/s、解压 325.1 MiB/s。

设计思路#

工程按职责分层:协议层定义 .sy 文件头、策略号、版本信息与归档写入入口;目录与数据编解码层负责扫描目录树、写入和读取目录块与数据块、条目解析与文件导出;算法与接口层提供 Huffman 与 AES 能力并抽象调用接口;策略装配层组合四种模式;业务主链路串联压缩与解压流程;并发层用两条 SafeQueue、WriteSorter 和 BufferPool 把读、算、写拆成三段流水线;编码与路径适配层统一 Qt 字符串、UTF-8 与 filesystem 路径之间的转换;GUI 后台层负责线程任务、进度回传、模式传参与策略自动探测;GUI 界面与启动层负责布局、多语言加载、输入校验与任务触发。

.sy 协议分三段:19 字节文件头、目录块区域、数据块区域。目录块前置分块标准,数据块按文件拆分,码长表与压缩数据各自带分块信息。格式版本为 3。

模块职责#

  • 文件头写入与定位:文件头写入、目录偏移回填、数据大小回填、块边界维护。
  • 目录读取:目录块读取、解密和标准项装配。
  • 条目解析:按条目类型解析目录项、文件项、逻辑根目录项和分割项。
  • 目录扫描:把输入路径转成目录树,BFS 序列化进目录块。
  • 压缩与解压主循环:串联整个流程,并作为流水线总指挥负责启停和收尾。
  • 并发组件:SafeQueue 是模板化管程队列,WriteSorter 按区段连续性给乱序到达的块定序,BufferPool 以定长块租借制造背压。
  • 数据读取与写出:原始数据按 8MB 分块读取;码长表、压缩数据和分块标准写出,支持偏移量回填。
  • 策略装配:按压缩模式组装 HuffmanAES、HuffmanOnly、AESOnly、PackOnly。
  • GUI:任务调度、进度回调、线程停止,不处理协议细节。

流程#

归档流程:输入路径列表 → 目录扫描 → 挂到逻辑根目录 → BFS 写成目录项和文件项。目录块按 16KB 分块,每块前写分块标准。目录块写完后回填目录偏移,文件体写完后回填数据大小。并发上由专职读线程装载目录并按块复制数据、分配全局递增序号,N 个计算工人各持一份私有模块做压缩和加密,专职写线程定序后纯追加写盘。

解压流程:读文件头取出策略号、版本号与目录偏移 → 逐块读取目录块,按 IV 决定是否解密 → 按条目类型拆成队列 → 先创建目录,再按文件队列进入数据区。解压侧复用同一套并发组件,数据区用专用只读流纯顺序读、按 compressedSize 记账切分文件边界,每块输出上限由读线程预计算,链接在普通文件和目录全部恢复后再重建。遇到同名文件会跳过,不覆盖现有文件。

数据流程:读取原始数据块 → 生成频率表、Huffman 树和码长表 → 写码长表、压缩块和有效位数,启用加密时再进 AES。归档只保存 258 字节的码长表,解压时据此还原 canonical 码并构建 12 位查找表,不需要重建整棵树。AES 密钥由 SHA-256 派生,协议层用 Windows CNG 提供的标准 AES-128-CTR,密钥流由 ECB 批量加密计数器块生成;每个数据块前置 16 字节随机 IV,密文长度与明文相同。

路径流程:Qt 输入 → UTF-8 → 核心层字符串 → 路径对象 → 文件系统。返回时反向转换。目录遍历、文件名序列化、解压输出目录拼接共用同一条转换链。

边界#

  • 协议层:文件头、目录块、数据区不依赖外部清单
  • 目录层:输入路径、逻辑根目录、BFS 队列、子项数量和目录恢复停在这一层
  • 数据层:压缩与解压主循环依赖算法接口,算法替换不改协议主流程
  • 并发层:队列、定序器、缓冲池只管序号与块所有权,不感知归档语义
  • 编码:转换工具统一处理,Qt、字符串、路径不脱离转换混用
  • GUI:界面层不接触目录块、文件头和数据区

性能#

指标数值
数据块大小8MB
目录缓冲16KB
并发模型专职读线程 + N 个计算工人,工人数默认取硬件并行度,取不到退 4,加专职写线程
测试数据13.47 GiB / 45,390 个文件的真实工程树
整体吞吐压缩 254.3 MiB/s,解压 325.1 MiB/s
相对单线程版本压缩 9.78 倍,解压 9.91 倍
内核单线程吞吐编码 471.1、解码 236.8、加密 1261.5、解密 1279.6 MiB/s
每个数据块的说明信息258 字节
发布形态静态链接的单 exe

测量口径、多核伸缩与瓶颈分析见性能报告。

限制#

程序面向 Windows,路径处理与文件系统行为按 Windows 规则组织,超过 260 字符的长路径不作为稳定能力承诺。

当前的瓶颈在读与写这条线上,不在压缩算法:完全不压缩也不加密时,16 个核心的吞吐与正常压缩加密完全相同,计算时间被完全藏在读写后面,再加核心也没有收益。

极端偏斜数据上解码会回退,12 位定长查表每个符号的成本高于原来的两步走树。


开发日志:SFC | 性能报告:v2.1.0 / v2.2.0 / v2.2.1 | 性能优化通用方法论

SFC:基于自定义 .sy 格式的文件归档工具
https://www.yonagi.world/posts/sfc-project-intro/
作者
YONAGI
发布于
2026-02-02
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
遠い日に想いを馳せて
Laplacian
封面
遠い日に想いを馳せて
Laplacian
0:00 / 0:00