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

使用O_CREAT、O_WRONLY获取文件当前位置并追加数据及socket写入文件问题

问题分析与修复方案

嘿,我看你代码里的核心问题一眼就找到了——你用了O_TRUNC这个标志!这玩意儿会在打开文件时直接清空所有现有内容,所以每次运行代码等于把旧文件删了重写,自然每次都是“新建”文件的效果,第一步必须把它删掉。

接下来一步步给你修复代码,同时解答你关于文件位置和追加的疑问:

1. 先把文件打开的标志改对

把打开文件的代码改成这样:

fd = open("/home/regs_p/cprograms/tcp/RSA.c", O_WRONLY | O_APPEND | O_CREAT, 0644);
  • 去掉O_TRUNC:彻底避免清空原有文件
  • 加上0644权限:用O_CREAT时必须指定文件权限,不然会生成权限全空的文件(连自己都可能打不开)
  • O_APPEND已经帮你搞定了追加逻辑:所有写操作都会自动定位到文件末尾,完全不需要手动找位置

2. 优化文件指针的使用逻辑

你现在每次循环里都调用fdopen(fd, "a+"),这是个低级错误——同一个文件描述符反复调用fdopen会生成多个独立的FILE指针,而且你从不关闭,会造成内存和文件资源泄漏。应该把fdopen移到循环外面,只打开一次:

if (fd < 0) {
    printf("Some problem with the file!");
} else {
    // 只初始化一次FILE指针,用"a"模式就够了(只写追加)
    fp = fdopen(fd, "a");
    if (fp == NULL) {
        printf("Failed to open file stream!");
        close(fd); // 出错时别忘了关闭文件描述符
        return;
    }
    while ((b = read(sockfd, buffer, sizeof(buffer) - 1)) > 0) {
        // 重点:用实际读取到的字节数b来写,不是sizeof(buffer)!
        // 不然buffer没读满的话,会把后面的垃圾数据也写进文件
        fwrite(buffer, 1, b, fp);
        // 可选:立即刷新缓冲区,确保数据实时写入文件(默认是缓冲到一定量才写)
        fflush(fp);
        // 获取当前文件位置,直接用ftell就行
        size = ftell(fp);
        // 可以加个打印验证:printf("Current file offset: %ld\n", size);
    }
    // 用完一定要关闭,资源泄漏是大忌
    fclose(fp);
    close(fd);
}

这里要特别注意fwrite的参数:你之前写的fwrite(buffer, sizeof(buffer), 1, fp)是把整个buffer当作一个元素写,但实际上你从socket只读到了b个字节,应该改成fwrite(buffer, 1, b, fp)——意思是写b个大小为1字节的元素,这样才是正确写入实际收到的数据。

3. 关于获取文件当前位置的疑问

当你用O_APPEND打开文件描述符,或者用"a"/"a+"打开FILE指针时,系统会自动保证所有写操作都在文件末尾,完全不需要手动调用fseek或者lseek。

如果确实需要手动获取当前位置:

  • 对FILE指针用ftell(fp),返回的是从文件开头到当前位置的字节数
  • 对文件描述符用lseek(fd, 0, SEEK_CUR),同样返回当前偏移量

另外多说一句:如果不用O_APPEND,想手动跳到末尾写,那可以用lseek(fd, 0, SEEK_END),但O_APPEND是原子操作,多进程/线程同时写文件时不会出现内容覆盖的问题,比手动seek安全多了。

额外提醒

  • 你的fd是static的,要注意如果这个函数被多次调用,别重复打开文件(可以在打开前先检查fd是否已经大于0)
  • read返回0表示客户端断开了连接,返回-1是出错,最好也处理这些情况,避免死循环
  • 如果是传输文本数据,确保socket传来的内容是正确的,但fwrite是按字节写的,不管文本还是二进制都没问题

内容的提问来源于stack exchange,提问作者Ace.McCloud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:42:49