误以写入模式加载.npy文件致损坏,求原因及恢复方法
意外以写入模式打开.npy文件导致损坏的原因及恢复方法
问题描述
加载.npy文件时,偶尔会因复制粘贴失误,误以写入(wb)模式而非读取(rb)模式打开文件,导致文件损坏,后续改用读取模式也无法加载。以下是最小复现示例:
import numpy as np a = np.array([0, 1]) # 保存数据 with open('tmp.npy', 'wb') as f: np.save(f, a) try: # 失误:以写入模式加载.npy文件 with open('tmp.npy', 'wb') as f: a = np.load(f) except: # 修正模式后尝试读取 with open('tmp.npy', 'rb') as f: a = np.load(f) # 触发错误:ValueError: Cannot load file containing pickled data when allow_pickle=False # a = np.load(f, allow_pickle=True) # 触发错误:OSError: Failed to interpret file <_io.BufferedReader name='tmp.npy'> as a pickle
加载时会触发ValueError,即使设置allow_pickle=True也会抛出OSError。
损坏原因
核心问题出在wb模式的文件操作逻辑上:
- 当用
wb(二进制写入)模式打开文件时,操作系统会立即将文件截断为0字节,直接清空原有所有内容,这个操作在打开文件的瞬间就完成了,和后续是否执行写入代码无关。 - 后续执行
np.load(f)时,这个函数是读取逻辑,不会向文件写入有效数据,但原文件的.npy格式数据已经被彻底清空,剩下的是空文件或无效碎片,自然无法被np.load识别解析。
能否恢复损坏的文件?
- 如果文件被
wb模式清空后,磁盘上没有被新的数据覆盖,部分专业数据恢复工具可能找回旧文件的碎片,但成功率极低,尤其是SSD开启TRIM功能的情况下,数据会被彻底擦除,几乎没有恢复可能。 - 一旦
wb模式打开后有新的写入操作,原数据被覆盖的部分就完全无法恢复。 - 总结:没有可靠的恢复方法,提前备份才是最优解。
避免此类问题的建议
- 直接使用numpy内置的简化接口:无需手动用
open()管理文件,直接调用np.save('tmp.npy', a)和np.load('tmp.npy'),numpy会自动处理正确的文件模式,从根源上避免模式错误。 - 若必须手动操作文件对象,加载时严格使用
rb模式,也可以在代码中增加模式检查逻辑,避免误操作。 - 对重要的.npy数据,定期备份或用版本控制工具(如Git)管理,降低数据丢失风险。
内容的提问来源于stack exchange,提问作者roygbiv
相关产品推荐
相关产品推荐

