You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:34:40