首页 > 解决方案 > 写入二进制文件时的 file.seek() 和 file.write() 问题

问题描述

因此,我将代码设置为读取数组并将其写入二进制文件。

import sys
import pickle
offset = 0
UncompressedLookup = {}
f = open('/Users/shivangisingh/Desktop/InformationRetrieval/UCIndex.txt', 'wb')
for k, v in uncompressed_dic.items():
    UncompressedLookup[k] = {'offset': offset,
                             'size': sys.getsizeof(v),
                             '#ofdocumnetsInCollection': termstats[k]['#ofdocumnetsInCollection'] ,
                             '#ofoccurancesInCollection' : termstats[k]['#ofoccurancesInCollection'] }
    f.seek(offset)
    pickle.dump(v,f)
    offset= f.tell()

f.close()

当我打印几次出现时UncompressedLookup

i=0
for k, v in UncompressedLookup.items():
    if (i==5):
        break
    print(k,v)

我得到:

scene {'offset': 0, 'size': 19152, '#ofdocumnetsInCollection': 747, '#ofoccurancesInCollection': 779}
venice {'offset': 5071, 'size': 1096, '#ofdocumnetsInCollection': 25, '#ofoccurancesInCollection': 78}

这很奇怪,因为当我从 0 开始并腌制 19152 字节的数据时,下一个偏移量应该是 19152,但我们可以看到它是 5071。我很困惑。

标签: pythonbinarybytepickle

解决方案


正如@Alex Hall 在评论中提到的那样,与放入文件sys.getsizeof()的数据大小没有任何关系。pickle要确定您需要/想知道什么,您可以将腌制数据临时存储在一个字符串中,您可以对其进行测量,然后自己手动将其写入文件。

您的问题没有重现问题的代码。但这里有一些简单的示例代码,展示了如何腌制字典中的项目并创建一个索引,以便以后使用 - 连同seek()- 随机读回其中的任何项目。(当然,假设这是你的最终目标。)

import random
import pickle

uncompressed_dic = {'a': 1, 'b': (2, 3, 4), 'c': 'text'}  # Sample data.

with open('UCIndex.txt', 'wb') as f:
    UncompressedLookup = {}
    offset = 0

    for key, value in uncompressed_dic.items():
        pkldata = pickle.dumps(value)
        size = len(pkldata)
        UncompressedLookup[key] = {'offset': offset, 'size': size}
        f.write(pkldata)
        offset += size


# Read items back in random order using UncompressedLookup dict.
keys = list(uncompressed_dic.keys())
random.shuffle(keys)

i = 0
while keys:
    if i >= 5:
        break
    key = keys.pop()
    offset = UncompressedLookup[key]['offset']
    size = UncompressedLookup[key]['size']
    with open('UCIndex.txt', 'rb') as f:
        f.seek(offset)
        pkldata = f.read(size)
        value = pickle.loads(pkldata)
    print((key, value))

样本输出:

('b', (2, 3, 4))
('c', 'text')
('a', 1)

推荐阅读