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

fwrite能否写入文件末尾之外?指定代码写法是否可行及实现方法

关于fwrite写入超出文件大小位置的问题

首先直接给结论:是的,fwrite允许写入超出当前文件大小的位置,这种操作会产生所谓的「文件空洞」——也就是文件中逻辑存在但实际未占用磁盘空间的0字节区域(具体是否占用磁盘取决于文件系统是否支持稀疏文件)。

不过你给出的代码并不能实现这个需求,原因出在文件打开模式上:

FILE *f = fopen("file.txt", "ab+"); 
fseek(f, NUMBER_BIGGER_THAN_FILE_SIZE, SEEK_SET); 
fwrite(&someStruct, sizeof someStruct, 1l, f);

ab+是追加读写模式,根据C标准的规定,当文件以追加模式(带a标志)打开时,所有写操作都会自动将文件位置指针重置到文件末尾,无论你之前用fseek定位到了哪里。所以你这里的fseek操作会被忽略,写入依然会追加到文件最后,达不到写入指定偏移位置的目的。

正确的实现方式

要实现在超出文件大小的位置写入,你需要使用读写模式但不带追加标志,比如r+b或w+b:

  • r+b:打开已存在的文件进行读写,不会截断文件;如果文件不存在,fopen会返回NULL。
  • w+b:打开文件进行读写,如果文件不存在则创建,存在则截断为0长度(会丢失原有内容)。

如果需要保留原有文件内容,同时支持写入任意位置(包括超出当前大小),可以先尝试用r+b打开,失败的话再创建文件:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    // 你的结构体定义示例
    int id;
    char name[20];
} SomeStruct;

int main() {
    const long NUMBER_BIGGER_THAN_FILE_SIZE = 1024 * 1024; // 示例偏移量
    SomeStruct someStruct = {123, "Test"};

    FILE *f = fopen("file.txt", "r+b");
    if (f == NULL) {
        // 文件不存在,创建新文件
        f = fopen("file.txt", "w+b");
    }
    if (f == NULL) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    // 定位到目标偏移位置
    if (fseek(f, NUMBER_BIGGER_THAN_FILE_SIZE, SEEK_SET) != 0) {
        perror("fseek failed");
        fclose(f);
        return EXIT_FAILURE;
    }

    // 写入结构体
    size_t written = fwrite(&someStruct, sizeof(SomeStruct), 1, f);
    if (written != 1) {
        perror("fwrite failed");
        fclose(f);
        return EXIT_FAILURE;
    }

    fclose(f);
    return EXIT_SUCCESS;
}

额外注意事项

  1. 文件空洞的特性:写入超出当前文件大小的位置后,文件的逻辑大小会变为NUMBER_BIGGER_THAN_FILE_SIZE + sizeof(someStruct),中间未写入的区域会被视为0字节。在支持稀疏文件的文件系统(如ext4、NTFS)中,这些空洞不会占用实际磁盘空间,直到你往里面写入数据。
  2. 错误检查:务必检查fopen、fseek、fwrite的返回值,避免因权限不足、磁盘满等问题导致操作失败却未被发现。

内容的提问来源于stack exchange,提问作者Mauricio Martinez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:37:06