如何在调用pclose()关闭进程前获取文件大小(压缩文件大小)
如何在调用pclose()关闭进程前获取文件大小(压缩文件大小)
嘿,我来帮你搞定这个问题!首先得明确一个关键细节:当你通过popen启动压缩进程(比如gzip这类工具)时,压缩程序通常会把数据暂存在缓冲区里,要么等缓冲区满,要么等收到「没有更多输入数据」的信号,才会把压缩后的内容真正写入磁盘文件。所以如果直接在pclose()前调用stat查文件大小,得到的大概率是不完整的数值——因为还有数据卡在缓冲区没刷到磁盘呢。
核心解决思路
- 如果你是通过管道往压缩进程写数据,先主动关闭管道的写端,让压缩进程知道输入已经结束,它就会自动把缓冲区里剩下的压缩数据写入文件。
- 等压缩进程处理完剩余数据后,再用
stat系统调用获取准确的文件大小,最后调用pclose()回收进程资源就没问题了。
完整代码示例
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <sys/stat.h> #include <sys/wait.h> int main() { FILE *pipe; char buffer[] = "Hello, world!"; struct stat fileStat; // 启动gzip进程,将压缩结果写入example.gz pipe = popen("gzip > example.gz", "w"); if (pipe == NULL) { perror("popen failed"); return 1; } // 往管道写入待压缩的数据 fwrite(buffer, sizeof(char), strlen(buffer), pipe); // 第一步:刷新管道缓冲区,确保所有数据都发给压缩进程 fflush(pipe); // 关闭管道写端,通知gzip没有更多输入数据了 pclose(pipe); // 第二步:获取准确的压缩后文件大小 if (stat("example.gz", &fileStat) == -1) { perror("stat failed"); return 1; } printf("Compressed file size: %lld bytes\n", (long long)fileStat.st_size); return 0; }
关键细节说明
fflush(pipe):强制把用户空间缓冲区里的数据写入管道,确保压缩进程能接收到所有待压缩的数据。pclose(pipe):这个函数会自动等待子进程(也就是这里的gzip)完全终止,只有当压缩进程把所有数据处理并写入文件后,它才会返回。这时候再用stat拿到的大小就是准确的压缩后文件大小。- 如果你非要在
pclose()执行前获取大小,只能尝试给压缩进程发送特定信号(比如部分工具支持SIGUSR1刷新缓冲区),但这种方式依赖工具特性,远不如上面的通用方法稳妥。
备注:内容来源于stack exchange,提问作者Pallavi Meher
相关产品推荐
相关产品推荐

