fast-compress-cj 实战手册:Snappy 类全 API 详解,从字符串到多类型数组全覆盖
【免费下载链接】fast-compress-cj一个快速的压缩/解压缩库项目地址: https://gitcode.com/Cangjie-TPC/fast-compress-cj
fast-compress-cj 是谷歌 Snappy 压缩算法的仓颉(Cangjie)移植版,一个开箱即用的高速压缩/解压缩库。它把 C++ 原生压缩能力封装成了纯仓颉友好的静态 API,让你用一行代码就能压缩 String、Int32、Float64 等各类数据,并提供完整的流式与帧式压缩方案,非常适合日志归档、消息队列、大数据缓存等对速度敏感的场景。
为什么选择 Snappy 压缩?
💡 压缩算法的选择通常要在"压缩率"和"速度"之间做取舍:
| 对比维度 | Snappy 表现 | 适用场景 |
|---|---|---|
| 压缩/解压速度 | ⚡ 极快,接近内存拷贝速度 | 网络传输、缓存层 |
| 压缩率 | 中等(略逊于 gzip) | 对体积不极敏感的数据 |
| 实现复杂度 | 低,API 极简 | 快速集成 |
| 跨语言兼容 | 与 C++/Java 生态互通 | 混合架构项目 |
一句话总结:用一点点压缩率换极大的吞吐速度。
三步跑起来:环境准备与快速验证
1. 编译原生依赖
库底层依赖 snappy 1.1.10 与 bitshuffle 0.3.4 两个 C 库,克隆到仓库根目录后执行编译脚本即可(Windows 同理用 build_win.bat):
./build_linux.sh完整步骤见 build_linux.sh 与 README.md 的"编译"章节。
2. 在 cjpm 中引入
项目包名为snappy4cj(见 cjpm.toml),依赖 charset4cj 提供字符编码支持:
[dependencies] charset4cj = {branch = "v1.0.0", git = "https://gitcode.com/Cangjie-TPC/charset4cj.git"}3. 三十秒压缩一个字符串
最小可用示例来自 test/DOC/example01.cj:
import snappy4cj.* let input: Array<UInt8> = "snappy test".toArray() let output = Snappy.rawCompress(input, UIntNative(input.size)) let m2 = String.fromUtf8(Snappy.uncompress(output))Snappy 类:一站式压缩 API 全景
核心类Snappy(src/snappy.cj)全部是静态方法,无需实例化。官方完整接口清单见 doc/feature_api.md。
一行压缩:compress() 支持的输入类型
compress是最常用的入口,通过参数类型自动选择实现:
| 输入类型 | 说明 |
|---|---|
String | 默认按 UTF-8 编码 |
String + encoding | 支持指定编码(字符串或 Charset 对象) |
Array<UInt8>/ 带偏移长度 | 原始字节,可做局部压缩 |
Array<Rune> | 字符数组 |
Array<Int16/Int32/Int64> | 整型数组 |
Array<Float32/Float64> | 浮点数组 |
定义位置见 src/snappy.cj#L46-L184。
零拷贝进阶:rawCompress() 与精确写入
如果不想额外分配输出数组,可以用带偏移参数的版本直接写入预分配缓冲区,返回实际压缩后的字节数:
// 从 input[inputOffset] 开始压缩 inputLength 字节, // 结果写入 output[outputOffset] 起的位置 public static func rawCompress(input: Array<Byte>, inputOffset: UIntNative, inputLength: UIntNative, output: Array<UInt8>, outputOffset: UIntNative): Int64各类型重载见 src/snappy.cj#L258-L327。
压缩前必做:长度预估与合法性校验
maxCompressedLength(byteSize):预分配输出缓冲区前,先算出压缩后的最大可能长度,避免缓冲区溢出(src/snappy.cj#L247)uncompressedLength(input):不解压就得知原始数据长度isValidCompressedBuffer(input):校验缓冲区是否为合法 Snappy 数据,处理不可信来源时必加(src/snappy.cj#L226)
按类型解压:uncompress* 系列 API 速查
压缩产物统一是Array<UInt8>,解压时按业务需要的类型选择对应方法:
| API | 返回类型 | 典型用途 |
|---|---|---|
uncompress | Array<UInt8> | 原始字节 |
uncompressString | String | 文本/日志,支持指定编码 |
uncompressCharArray | Array<Rune> | 字符序列 |
uncompressShortArray | Array<Int16> | 16 位整型 |
uncompressIntArray | Array<Int32> | 32 位整型 |
uncompressLongArray | Array<Int64> | 64 位整型 |
uncompressFloatArray | Array<Float32> | 单精度浮点 |
uncompressDoubleArray | Array<Float64> | 双精度浮点 |
以上每个方法都提供"整段"和"指定 offset/length 局部解压"两种重载,行号区间见 src/snappy.cj#L363-L702。
🎯选型建议:内存敏感场景用整段 API;大文件中只取片段时用 offset/length 重载,避免全量解压。
流式压缩:SnappyOutputStream 与 SnappyInputStream
数据大到放不进内存时,改用流式方案:
- SnappyOutputStream(src/snappy_output_stream.cj):包装任意
OutputStream,构造时可指定块大小blockSize及缓存分配器工厂;write支持Array<UInt8>、Array<Float32/Float64>、Array<Int16/Int32/Int64>等多种类型直接写入,写完记得close()刷新尾部块。 - SnappyInputStream(src/snappy_input_stream.cj):对称的读取端,
read同样支持上述全部类型数组,还支持rawRead按字节偏移精确定位、available()查询剩余数据量。
完整示例见 test/DOC/example02.cj——写、关、读、断言一气呵成。
帧式流:自带 CRC 校验的 SnappyFramed 系列
帧(Framed)格式是 Snappy 生态的"标准信封",适合跨系统传输和文件持久化:
- SnappyFramedOutputStream(src/snappy_framed_output_stream.cj#L45-L57):可配置块大小、最小压缩比和缓冲池;除了常规
write,还提供transferFrom支持直接从输入流/ByteBuffer 搬运数据。 - SnappyFramedInputStream(src/snappy_framed_input_stream.cj#L38-L50):构造时传入
verifyChecksums: Bool即可开启CRC32C 校验,防数据损坏,这是普通流没有的安全能力;transferTo可整体搬运到目标 ByteBuffer。
完整示例见 test/DOC/example03.cj。
BitShuffle:数值数组的压缩率增强器
💡 对数值数组(尤其整型)直接 Snappy 压缩,效果往往不理想——把每个数的"高位字节"和"低位字节"交错重排后再压缩,压缩率显著提升。
BitShuffle(src/bit_shuffle.cj)提供成对 API:
shuffle(Int16/Int32/Int64/Float32/Float64 数组):按BitShuffleType重排字节,返回Array<UInt8>unshuffleShortArray/IntArray/LongArray/FloatArray/DoubleArray:精确还原
典型链路:shuffle → Snappy.compress → 传输 → Snappy.uncompress → unshuffle,适合时序数据、数值日志等场景。类型枚举定义见 src/bit_shuffle_type.cj。
异常处理与错误码
所有可预期失败都以异常形式抛出,便于精确定位:
SnappyError/SnappyIOException:携带SnappyErrorCode错误枚举与消息,见 src/snappy_error.cj、src/snappy_i_o_exception.cjSnappyErrorCode(src/snappy_error_code.cj):涵盖本地库加载失败、解析错误、内存溢出、空输入、版本不适配等 11 种错误,还提供getErrorMessage(id)反查错误描述。
推荐写法:捕获SnappyError后通过getErrorCode()分支处理,而不是笼统吞掉异常。
核心文件导航
| 模块 | 路径 | 作用 |
|---|---|---|
| 核心 API | src/snappy.cj | 压缩/解压全部静态方法 |
| 流式输出 | src/snappy_output_stream.cj | 边写边压 |
| 流式输入 | src/snappy_input_stream.cj | 边读边解压 |
| 帧式输出 | src/snappy_framed_output_stream.cj | 带块头与校验 |
| 帧式输入 | src/snappy_framed_input_stream.cj | 支持 CRC 校验 |
| 字节重排 | src/bit_shuffle.cj | 数值数组预压缩 |
| 错误定义 | src/snappy_error_code.cj | 11 种错误码 |
| API 文档 | doc/feature_api.md | 全量接口参考 |
| 示例代码 | test/DOC/ | 三个可运行示例 |
写在最后
fast-compress-cj 的 API 设计非常"直给":
- 小数据→
Snappy.compress/Snappy.uncompress*一对方法搞定,9 种输入类型全覆盖; - 大数据→ 换
SnappyOutputStream/SnappyInputStream流式处理; - 跨系统/需防篡改→ 用
SnappyFramed帧式流开启 CRC 校验; - 数值数组追求更高压缩率→ 先过一道
BitShuffle。
配合 CHANGELOG.md 跟踪版本变更,按需选择 API 组合,基本能覆盖从字符串日志到浮点矩阵的全部压缩需求。
【免费下载链接】fast-compress-cj一个快速的压缩/解压缩库项目地址: https://gitcode.com/Cangjie-TPC/fast-compress-cj
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考