截断和重写泡菜文件会引发KeyError'\ x00'

时间:2018-08-06 11:03:27

标签: python file pickle python-2.x truncate

在我转储数据后,我试图截断泡菜文件,但它似乎不像.txt文件那样工作。

dic1 = {'a': 1, 'b': 2}
dic2 = {'c': 3, 'd': 4}
f = open("data.pk", "wb+")
pickle.dump(dic1, f)
f.truncate(0)
pickle.dump(dic2, f)
f.seek(0)
print pickle.load(f)
f.close()

此代码引发KeyError:'\ x00'。似乎truncate(0)不会截断文件,但会添加一些字符,例如'\ x00'。

是否可以在不关闭并重新打开泡菜文件的情况下删除它的内容?

1 个答案:

答案 0 :(得分:0)

file.truncate更改文件大小,但是根据docs

  

当前文件位置不变。

这可以通过在截断后调用文件的tell方法来证明。

>>> d1 = dict(a=1, b=2)
>>> d2 = dict(c=3, d=4) 

>>> with open('file.bin', 'wb+') as f:
...     pickle.dump(d1, f)
...     f.truncate(0)
...     print 'File pointer position:', f.tell()
...     pickle.dump(d2, f)
...     f.seek(0)
...     pickle.load(f)
... 
File pointer position: 30
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
  File "/usr/lib64/python2.7/pickle.py", line 1384, in load
    return Unpickler(file).load()
  File "/usr/lib64/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
KeyError: '\x00'

将文件指针重置为文件开头会产生所需的行为 *

>>> with open('file.bin', 'wb+') as f:
...     pickle.dump(d1, f)
...     f.truncate(0)
...     f.seek(0)
...     pickle.dump(d2, f)
...     f.seek(0)
...     pickle.load(f)
... 
{'c': 3, 'd': 4}

* 至少,它会在我的Linux机器上产生所需的行为。对this question的评论中的讨论表明,这可能不适用于所有平台。