不能直接用lz4_compress_default压缩文件,因其仅处理内存块,不支持文件i/o、帧头、校验或流式读写;必须使用lz4frame.h提供的lz4f_compressframe等api生成标准.lz4格式文件,才能确保兼容性和完整性。

直接用 LZ4_compress_default 压缩文件基本不可行——它只处理内存块,不带文件I/O、帧头、校验或流式读写逻辑。想“极速压缩文件”,必须自己组装这些环节,否则要么崩溃,要么生成损坏/无法解压的二进制。
为什么不能直接传 fopen 文件指针给 LZ4_compress_default
LZ4_compress_default 的签名是:int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity)。它只认内存地址和长度,完全不感知文件、路径、句柄或缓冲区生命周期。
- 常见错误:把
FILE*强转成const char*传进去 → 内存越界或随机崩溃 - 真实需求不是“调一个函数”,而是“把磁盘文件读入内存→压缩→写回磁盘”这一整条链路
-
LZ4官方库默认不提供.lz4文件格式支持(含魔数、块描述、校验),需手动实现或依赖lz4frame模块
推荐做法:用 LZ4F_compressFrame 生成标准 .lz4 文件
这是最接近“开箱即用”的方案,生成的文件能被 lz4 命令行工具、Python lz4 包等直接识别和解压。
- 必须链接
liblz4并启用LZ4F(CMake 中加find_package(LZ4 REQUIRED),编译时加-llz4) - 先调
LZ4F_createCompressionContext初始化上下文,再用LZ4F_compressBegin写帧头 - 分块读文件(如每次
64KB),每块调LZ4F_compressUpdate,避免单次加载整个大文件到内存 - 最后用
LZ4F_compressEnd写尾部,确保帧完整 - 错误检查不能省:
LZ4F_isError必须包裹每个LZ4F_*调用返回值
性能关键点:别让 I/O 或内存分配拖慢 LZ4
LZ4 本身解压缩可达 GB/s 级,但实际文件压缩速度常卡在磁盘或 malloc 上。
- 输入缓冲区建议设为
128KB~1MB(太小增加系统调用次数,太大浪费内存) - 输出缓冲区要预留足够空间:
LZ4F_compressBound(srcSize, &prefs)计算上限,别硬写固定大小 - 禁用 C 运行时缓冲:
setvbuf(inFile, nullptr, _IONBF, 0)和setvbuf(outFile, nullptr, _IONBF, 0),尤其在 Linux 下可减少一层 memcpy - 如果源文件支持
mmap(如普通磁盘文件),用mmap替代fread可进一步减少拷贝,但注意munmap时机
最容易被忽略的坑:压缩失败时的 dstCapacity 不足与静默截断
LZ4_compress_default 返回值是实际压缩字节数,但如果 dstCapacity 不够,它会返回 0(不是负数!),且不报错——你可能误以为“空数据压缩成功”,结果写入零字节文件。
- 永远检查返回值是否 > 0,且 ≤
dstCapacity - 若返回 0,说明目标缓冲区不够,应重试(增大
dstCapacity或改用流式 API) - 用
LZ4_compressBound(srcSize)预估最大输出长度,但注意这只是上界,实际输出通常小得多 - 调试时可在压缩后立即用
LZ4_decompress_safe解回内存做一致性校验(仅开发期,别放生产)
真正快的不是 LZ4 函数本身,而是你绕过文件系统瓶颈、避开内存误操作、并正确处理帧边界的能力。标准 .lz4 格式支持和流式分块是必选项,硬塞 LZ4_compress_default 到文件流程里只会得到不可靠的二进制垃圾。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











