class PickleNumberStorage:
"""使用Pickle二进制存储单个数值"""
def __init__(self, filename='data.pkl', default=0):
self.filename = filename
self.default = default
if not os.path.exists(filename):
self.write(default)
def write(self, value):
"""原子写入新值"""
temp_file = self.filename + '.tmp'
with open(temp_file, 'wb') as f:
pickle.dump(value, f, protocol=pickle.HIGHEST_PROTOCOL)
os.replace(temp_file, self.filename) # 原子替换
def read(self):
"""读取存储的值"""
try:
with open(self.filename, 'rb') as f:
return pickle.load(f)
except (FileNotFoundError, pickle.PickleError):
return self.default
class MMapNumber:
"""使用内存映射高效存储单个数值(双精度浮点/长整型)"""
def __init__(self, filename: str = 'data.bin', default: float = 0.0):
"""
初始化内存映射文件
:param filename: 数据文件路径
:param default: 文件不存在时的默认值
"""
self.filename = filename
self.default = default
self._init_file()
def _init_file(self):
"""确保数据文件存在并正确初始化"""
if not os.path.exists(self.filename):
with open(self.filename, 'wb') as f:
f.write(struct.pack('d', self.default))
def write(self, value: Union[float, int]):
"""写入新值(原子操作)"""
with open(self.filename, 'r+b') as f:
with mmap.mmap(f.fileno(), 8) as mm:
mm[:8] = struct.pack('d', float(value))
def read(self) -> float:
"""读取当前值"""
with open(self.filename, 'r+b') as f:
with mmap.mmap(f.fileno(), 8) as mm:
return struct.unpack('d', mm[:8])[0]
def __enter__(self):
"""支持上下文管理器"""
self.file_obj = open(self.filename, 'r+b')
self.mm = mmap.mmap(self.file_obj.fileno(), 8)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""自动关闭资源"""
self.mm.close()
self.file_obj.close()
def get_handle(self):
"""获取低级操作句柄(高级用户使用)"""
return open(self.filename, 'r+b'), mmap.mmap(self.file_obj.fileno(), 8)