我经常使用
pickle.dump()
在 Python 2.7 中保存大文件。在我的代码中,我有一个 .pickle
文件,我会在代码的每次迭代中不断更新该文件,每次都会覆盖同一个文件。
但是,我偶尔会遇到崩溃(例如由于服务器问题)。这可能发生在pickle转储的中间,导致pickle不完整并且pickle文件不可读,并且我丢失了过去迭代中的所有数据。
我想我可以做到的一种方法是为每次迭代保存一个
.pickle
文件,然后将所有这些文件合并起来。是否有其他推荐的方法或写入磁盘的最佳实践可以防止崩溃?
您正在有效地进行备份,因为您的目标是相同的:灾难恢复,丢失尽可能少的工作。
在备份中,有以下标准做法,因此请选择最适合您的做法:
还有其他推荐的方法,或者最佳实践吗?
让我提一下 Mike McKearn 的一个很酷的
dill
包
import dill as pickle
pickle.dump_session( aRotatingIndexFileNAME ) # saves python session-state
# # session is worth
# # many computing [CPU-core * hrs]
如果需要,只需
import dill as pickle; pickle.load_session( aLastSessionStateFileNAME )
使用旋转文件名是归档到一定深度的回滚功能的常见最佳实践,因此值得在此不再重复。
dill
在这方面确实帮了我的忙,包括故意使用相同的调用签名,以便轻松替换到 python 项目中。
问题是写入文件不是原子的。
与保存相反,您使用临时pickle文件并将其重命名为正确的名称,因为重命名是原子的
在这种情况下,即使崩溃后,你的pickle文件也会正常,但它可能会丢失一些数据,这些数据在崩溃时写入临时文件(重命名之前)
CACHE_FILEPATH = 'cache.pkl'
# Open save pickle file
try:
with open(CACHE_FILEPATH, 'rb') as f:
CACHE_DICT = pickle.load(f)
except:
CACHE_DICT = {}
# ====
# Some more code...
# ====
# Save pickle file
tmp_filename = CACHE_FILEPATH + '.tmp' # XXX: Save to .tmp file first
with open(tmp_filename, 'wb') as f:
pickle.dump(CACHE_DICT, f)
os.replace(tmp_filename, CACHE_FILEPATH) # XXX: Chash-safe atomic rename