磁盘写满时存档损坏:fopen "wb" 模式会先把文件清零
January 25, 2026About 2 min
磁盘写满时存档损坏:fopen "wb" 模式会先把文件清零
有个只在磁盘接近写满时才复现的存档 bug:读档、存档时崩溃,而且存档文件变成 0 字节的空文件。根因是写文件用了 "wb" 模式——它会先把原文件截断清零,此时如果磁盘没空间写入新内容,原存档就被毁了。
复现步骤
这个 bug 很难自然遇到,得刻意把磁盘填满:
- 跑游戏,在 C 盘生成存档。
- 用管理员权限开 cmd。
dir看当前可用空间 X。fsutil file createnew C:\file.txt X用一个占满剩余空间的大文件把磁盘填满。- 再跑游戏读档并存档 —— 崩溃,且存档变成 0 字节空文件。
两个成因
其一,系统盘的可用空间不稳定。 C 盘(系统盘)的剩余空间会被系统或其他进程动态占用,"刚好为空"这个状态维持不住。把存档挪到其他非系统盘就不复现——因为其他盘不会被系统随时抢占空间。
其二,"wb" 模式会破坏原文件。 游戏代码用这种方式打开文件写入:
if (fopen_s(&m_FileDes, path, "wb") == 0)
{
// 写入存档数据
}
实测下来,用 "wb" 模式打开文件时,它会先截断(清空)原文件、把原来占的磁盘空间释放出来——而这块刚释放的空间会被其他程序或系统立刻抢走。于是轮到真正写入时已经没空间了,写入失败,原存档也回不来了,最终留下一个 0 字节文件。
规避
- 写存档前先检查可用空间,空间不足就不要动原文件、直接给玩家报错。
- 写临时文件 + 原子替换:先把新存档写到临时文件,确认写成功后再 rename 覆盖原文件。这样即便中途失败,原存档也完好——这是存档写入的通用安全做法,比直接
"wb"覆盖稳得多。 - 存档尽量别只放系统盘:系统盘空间被动态占用,是这个 bug 的外部诱因。