fwrite
定义
fwrite是C语言标准库提供的格式化无关的数据写入函数,原型为size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream),其中size_t是无符号整型返回类型[1][5]。参数ptr指向内存中数据区的起始位置,size表示单个元素的字节长度,nmemb表示待写元素的数量,stream指向一个已由fopen打开的文件流[3][2]。函数对这些元素的处理并不依赖元素的数据类型,只按连续字节解读,因此结构体、数组、浮点数等对象都可以整体写出[2]。
函数返回实际写入的元素个数,在出错时该值可能小于请求的nmemb;若size或nmemb为0,则返回0且流的状态保持不变[1][6]。写入过程会推进流的文件位置指示器,推进量等于成功写出的字节数;一旦发生错误,位置指示器的取值不再有确定含义[1]。
原理
从语义上看,fwrite把ptr处的每个对象视为一段unsigned char序列,再对该序列逐字节调用fputc完成输出,相当于连续写size×nmemb个字节[1][7]。因此写出的字节数可以表示为 $N = size \times nmemb$,而返回值的单位是元素而非字节,只有当size等于1时,返回的元素个数才等同于字节数[4]。
数据先进入用户空间缓冲区,并不立即落到存储介质上,需要调用fflush或fclose才会把缓冲区内容同步到文件[3]。数据的实际落点取决于流的打开模式:以w+方式打开时,写入从当前文件指针所在位置开始并覆盖原有内容;以a+方式打开时,写入追加到文件末尾[3]。
flowchart LR
A[内存中的数组 ptr] --> B[按 unsigned char 逐字节拆解]
B --> C[逐个传给 fputc]
C --> D[流缓冲区 stream]
D --> E[fflush 或 fclose 同步]
E --> F[文件]
在文本模式下,换行符可能被转换为回车加换行的组合,而这种转换不会改变函数的返回值[2]。
发展历程
fwrite随C语言标准库的标准化而列入ISO/IEC 9899,C89/C90标准的相关条款编号为4.9.8.2,C99标准为7.19.8.2,此后的C11、C17、C23等版本沿用同一编号体系并保留该函数[7]。在C99版本中,函数原型为pointer参数与stream参数补充了restrict限定符,用以说明两个指针所指向的对象在调用期间不会重叠[7][8]。
该函数同时被纳入POSIX标准,在IEEE Std 1003.1中被列为二进制输出接口,并规定了返回值、错误指示器与errno的处理方式[1]。各家C运行库在标准之外还做了扩展,例如微软C运行时提供不加锁的_fwrite_nolock版本,并说明在Unicode转换模式下缓冲区会被解释为UTF-16数据[2]。
应用
fwrite的典型用途是把内存中的结构化数据整块写入文件,例如将结构体变量、浮点数组或字符数组保存到以wb模式打开的二进制文件,再用fread读回,形成简单的数据持久化方案[3][7]。在数据库、图像处理与序列化库等需要按固定记录长度存取的场合,以元素为单位计数的写入方式便于与记录结构对应[4]。
由于返回的是成功写入的元素个数,程序可以据此判断是否发生短写;若返回值小于nmemb,通常意味着写入过程中出现错误,此时应检查流上是否已置错误指示器[1][4]。部分实现会在size与nmemb乘积溢出时返回0并把errno设为EOVERFLOW,这类处理属于具体实现的扩展行为[9]。
局限
fwrite不负责格式转换,也不会自动补充分隔符或换行,写出的字节完全取决于内存中的原始表示[1]。由于不同平台的数据类型长度与字节序可能不同,用它写出的文件带有实现依赖性,换一个应用程序或换一种处理器后未必能用fread正确读回[1][6]。
该函数在遇到空字符时并不会停止拷贝,若把以空字符结尾的字符串按strlen计算的长度传入,得到的结果将缺少结尾的空字符,读回时可能不再是合法的字符串[5][8]。因此向文件写入此类字符串时,元素个数需要按字符串长度加1计算[5]。
函数本身不进行缓冲区边界检查,参数中的长度若超过实际数据区大小,就会读取到数据区之外的字节[5]。此外,写入仅到达用户空间缓冲区,在fflush或fclose之前不能假定内容已经持久化保存[3]。
参见
参考资料
- fwrite [引用日期2026-10-29]
- fwrite [引用日期2026-10-29]
- 图文详情——科普中国资源服务 [引用日期2026-10-29]
- fread, fwrite [引用日期2026-10-29]
- viewpagesrc [引用日期2026-10-29]
- man pages section 3: Basic Library Functions [引用日期2026-10-29]
- fwrite [引用日期2026-10-29]
- diffpagesbyversion [引用日期2026-10-29]
- OpenBSD manual page server [引用日期2026-10-29]