如何在C语言中计算ZSTD压缩文件大小?代码结果异常求助
ZSTD压缩后文件大小异常的问题排查
我用ZSTD实现文件压缩,测试文件test.txt的内容如下:
LWpSxCFgUh
BmmJnEHaYG
urlMrzBDFW
jkYpByALnm
UVaOzGwWkO
pUmAAglAnE
AXDeSGPpFe
IrIItGYEwC
pOrhUHPsMh
IdtdfAofXN
eRZLTEirRt
OQkrVFtqfY
JEQFixzifR
dwreUUZYVV
EkrIobWWfQ
oCfdaXrlPi
WGopEbfHGy
bSxtEulqWH
OuualBJWHa
XVsqhFTECO
预期压缩前文件大小为220,压缩后为194,但实际输出的压缩后大小是18,使用的代码如下:
void compresszstd(const char *input,const char *output) { // size_t const fBuff_size = (size_t)fileSize; //input file size void *const fBuff = malloc(fBuff_size); //input file buff size_t const cBuff_size = ZSTD_compressBound(fBuff_size); // compressed size void *const cBuff = malloc(cBuff_size);// compressed data // compress input buff and get size of compressed file size_t const c_size = ZSTD_compress(cBuff, cBuff_size, fBuff, fBuff_size, 1); fwrite(&cBuff, 1, c_size, output); fprintf(stdout, "%u\n%u\n", (unsigned)fBuff_size, (unsigned)c_size); }
问题分析与修正
核心错误:
fwrite参数传递错误
代码中fwrite(&cBuff, 1, c_size, output);是错误的:&cBuff取的是指针变量本身的内存地址,而非压缩后数据所在的缓冲区地址。cBuff本身就是指向压缩结果的指针,正确写法应为:fwrite(cBuff, 1, c_size, output);之前的错误操作导致你写入的是指针的内存值(通常4/8字节),却写了18字节,输出文件并非真实的ZSTD压缩数据,所以显示的"18"是错误写入的字节数,不是真实压缩结果大小。
额外需要验证的点
- 代码中缺少读取输入文件到
fBuff的逻辑,必须确保用fread(fBuff, 1, fBuff_size, inFile)将文件内容完整读入缓冲区,否则压缩的是未初始化的垃圾数据,结果必然异常。 - 要检查
ZSTD_compress的返回值是否为错误状态,用ZSTD_isError(c_size)判断,若为错误需终止流程并提示:if (ZSTD_isError(c_size)) { fprintf(stderr, "ZSTD压缩错误: %s\n", ZSTD_getErrorName(c_size)); return; } - 确认
fileSize的获取逻辑正确,保证其值为测试文件的真实大小220字节(20行×11字符/行,含换行符)。
- 代码中缺少读取输入文件到
修正后的关键代码片段:
// 补充文件打开与读取逻辑 FILE *inFile = fopen(input, "rb"); FILE *outFile = fopen(output, "wb"); size_t readSize = fread(fBuff, 1, fBuff_size, inFile); if (readSize != fBuff_size) { fprintf(stderr, "读取输入文件失败\n"); return; } size_t const c_size = ZSTD_compress(cBuff, cBuff_size, fBuff, fBuff_size, 1); if (ZSTD_isError(c_size)) { fprintf(stderr, "ZSTD压缩错误: %s\n", ZSTD_getErrorName(c_size)); return; } fwrite(cBuff, 1, c_size, outFile); // 修正后的写入操作
内容的提问来源于stack exchange,提问作者Jonah KIM
相关产品推荐
相关产品推荐

