扩展库 / zstd
zstd
压缩归档
v1.0.0
C 混编
0 依赖
ABI 1
Zstandard(zstd)高速无损压缩 — 由 Facebook 开发,在压缩率与速度之间取得极佳平衡,广泛用于实时传输与存储。C 层内嵌 zstd 1.6.0 合并版引擎,xlang 层提供二进制安全(统一 Buffer)、易用的 API:一次性内存压缩、文件级压缩、以及 update → drain → finish 增量流式处理。
典型场景
实时传输压缩
日志压缩
大文件分块流式
数据库页面压缩
备份存储
进度回显传输
快速开始
quick_start.xl
import zstd
func main(...) as int
// 一次性压缩 / 解压(Buffer 二进制安全)
Buffer packed = zstd.compress("hello zstd")
println(zstd.decompressText(packed)) // hello zstd
// 增量流式:update 喂数据 -> drain 取产出 -> finish 封存
auto enc = zstd.compressor()
enc.update("part1 ")
enc.update("part2")
enc.finish()
Buffer blob = enc.drain()
auto dec = zstd.decompressor()
dec.update(blob)
dec.finish()
println(dec.drain().text()) // part1 part2
return 0
end核心特性
- 极速压缩 — zstd 在默认级别 3 即可达到极高吞吐,负数级别更快(最低 -131072)
- 二进制安全 — 输入输出统一
Buffer,避免字符串 NUL 截断 - 三种粒度 — 一次性内存、文件级、增量流式(
ZstdCompressor/ZstdDecompressor) - 真流式输出 —
drain()随时取走已产出字节,内存占用可控 - 进度回显 —
inputBytes/outputBytes字节计数器 - 多帧流 — 解压器
finished/members支持串联多帧 zstd 流 - 宽级别范围 — -131072..22,从极速到最高压缩率自由权衡
- 文件原子写 — 临时文件 + 原子重命名,支持 UTF-8 路径
包信息
| 包名 | zstd |
|---|---|
| 版本 | 1.0.0 |
| 引擎 | zstd 1.6.0(合并版单文件) |
| 实现方式 | C 混编(zstd 引擎 C,API 层 xlang) |
| 依赖 | 无 |
| ABI 版本 | 1 |
| 导出符号 | compress(), decompress(), decompressText(), compressFile(), decompressFile(), compressor(), decompressor(), ZstdCompressor, ZstdDecompressor, ZSTD_* 常量 |
| 源文件 | extlibs/zstd/src/zstd.xl |
常量
export const int ZSTD_MIN_LEVEL = -131072
export const int ZSTD_MAX_LEVEL = 22
export const int ZSTD_DEFAULT_LEVEL = 3
压缩级别常量。负数级别速度更快,正数级别压缩率更高;默认 3 为速度与压缩率平衡点。
一次性压缩 / 解压
export func compress(Buffer data, int level = 3, int maxInput = 268435456, int maxOutput = 536870912) as Buffer
export func compress(string text, int level = 3, ...) as Buffer
整块压缩。level 为压缩级别 -131072..22(默认 3)。
level 越界抛 ValueError;超限或失败抛 CompressionError。export func decompress(Buffer data, int maxInput = 268435456, int maxOutput = 536870912, int maxRatio = 1000) as Buffer
export func decompressText(Buffer data, ...) as string
整块解压。maxRatio 限制解压放大倍数,防御压缩炸弹。
文件级压缩 / 解压
export func compressFile(string source, string destination, int level = 3, bool overwrite = true, ...)
export func decompressFile(string source, string destination, bool overwrite = true, ...)
文件到文件,走 XRT reader/writer,临时文件 + 原子重命名。
末尾可传
(func(int inputBytes, int totalBytes, int outputBytes) as bool)? onProgress = null。返回 false 会删除临时输出并抛 CancelledError;回调异常原样传播。C 层使用 xrtprogressproc + void* userData,语义一致。工厂函数
export func compressor(int level = 3, ...) as ZstdCompressor
export func decompressor(int maxInput = 268435456, ...) as ZstdDecompressor
创建增量流式压缩器 / 解压器。
ZstdCompressor 类
func update(Buffer data) / update(string text)
func drain() as Buffer
func finish() as bool
get inputBytes as int / get outputBytes as int
update:喂入数据。drain:取走已产出压缩字节。finish:封存帧。计数器用于进度回显。
ZstdDecompressor 类
func update(Buffer data)
func drain() as Buffer
func finish() as bool
get inputBytes / outputBytes / finished / members
members > 1 表示串联多帧流;finished 在流结束时为 true。
教学范例
完整源文件:examples/extlibs/zstd.xl
1. 一次性压缩 / 解压
一次性
import zstd
Buffer source = Buffer()
source.append("xlang zstd ")
source.appendByte(0)
source.appendByte(255)
Buffer packed = zstd.compress(source)
Buffer plain = zstd.decompress(packed)
assert plain == source
println("引擎版本: ", zstd.version())2. 增量流式压缩
流式压缩
auto encoder = zstd.compressor()
Buffer streamPacked = Buffer()
encoder.update("hello ")
streamPacked.append(encoder.drain())
encoder.update("stream")
streamPacked.append(encoder.drain())
encoder.finish()
streamPacked.append(encoder.drain())
println("喂入 ", encoder.inputBytes, " 字节, 产出 ", encoder.outputBytes, " 字节")3. 流式解压 + 多帧统计
流式解压
auto decoder = zstd.decompressor()
Buffer restored = Buffer()
decoder.update(streamPacked)
restored.append(decoder.drain())
decoder.finish()
restored.append(decoder.drain())
assert restored.text() == "hello stream"
println("帧数: ", decoder.members)4. 最高级别 L22
调优
auto tuned = zstd.compressor(zstd.ZSTD_MAX_LEVEL)
tuned.update("tune me")
tuned.finish()
assert zstd.decompress(tuned.drain()).text() == "tune me"5. 损坏检出
错误处理
streamPacked[10] = streamPacked[10] ^ 255
try
zstd.decompress(streamPacked)
catch CompressionError e
println("已拒绝损坏数据")
end运行范例
终端
cd release xl.exe run examples\extlibs\zstd.xl
测试覆盖
测试文件:test/cases/extlib_zstd.xl、test/cases/extlib_zstd_progress.xl
- 一次性 compress / decompress 二进制往返(含 NUL / 0xFF)
- 流式 compressor update / finish / drain 往返
- 解压器 members 帧计数(单帧 == 1)
- 流式分块收集 + inputBytes 计数器
- 解压器 finished 状态
- 最高级别 ZSTD_MAX_LEVEL 往返
- 级别越界(99)抛 ValueError
- 串联多帧流(members == 2)
- 损坏数据抛 CompressionError
- 文件级往返 + overwrite 拒绝
运行测试
终端
cd release xl.exe run ..\test\cases\extlib_zstd.xl