写入二进制文件时出现file.seek()和file.write()问题

时间:2018-10-05 23:22:01

标签: python binary byte pickle

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

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。我很困惑。

1 个答案:

答案 0 :(得分:1)

正如@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)