C语言中fwrite与write写入学生信息文件大小不一致问题排查
问题原因分析与解决方法
这个问题我之前在Windows平台写C代码时也碰到过,大概率是文本模式与二进制模式的换行转换差异搞的鬼,具体拆解如下:
核心原因:Windows下的文件模式差异
在Visual Studio所在的Windows环境中,文件操作分两种模式,二者对换行符的处理完全不同:
- 当你用
fwrite写入时,如果是通过fopen("xxx", "wb")以二进制模式打开文件,标准库会直接把内存里的字节原样写入磁盘,不会对任何字符做转换。所以1000个32字节的Student结构体总大小刚好是32*1000=32000字节,符合预期。 - 而使用
write系统调用时,如果你打开文件时指定了O_TEXT模式(Windows对open函数的扩展标志),操作系统会自动把内存中的换行符'\n'(ASCII 0x0A)转换成Windows标准的换行格式'\r\n'(ASCII 0x0D+0x0A),每个'\n'都会多占1字节。如果你的1000条学生信息里,name字段总共包含21个'\n'字符,write时就会额外写入21个'\r'字节,最终文件大小就变成了32000+21=32021字节。
其他小概率排查方向
当然也有可能是代码逻辑问题:比如循环写入Student时,某次write的长度参数写错(比如误写了strlen(student.name)+...而非sizeof(Student)),或者循环次数错误导致多写了部分数据,但这种情况通常会导致文件大小差异更大,不如模式问题常见。
验证与解决方法
- 验证方法:用二进制编辑器分别打开两个文件对比字节差异,你会发现
write生成的文件里多了21个0x0D('\r')字节,正好对应原始数据中的'\n'。 - 解决方法:打开文件时强制使用二进制模式,在
open的标志中加上O_BINARY:
int fd = open("student.dat", O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0644);
这样write就会和fwrite的二进制模式行为一致,直接写入内存中的原始字节,不会做任何换行转换,文件大小就会恢复到预期的32000字节。
内容的提问来源于stack exchange,提问作者임도경
相关产品推荐
相关产品推荐

