Искать в файле, полном маринованных объектов - PullRequest
0 голосов
/ 07 апреля 2011

У меня есть этот огромный файл с объектами, предположим, что:

for object in objects:
   pickle.dump(myfile,object)

Объекты разного размера, хотя они одного типа.
Файл заполняется в течение длительного времениВ некоторых случаях, но время от времени, когда процесс дампа перезапускается, мне нужно читать последние объекты.
Примерно так:

 myfile.seek(-1000,2)
 while myfile.tell() < mysize:
    objects.append(pickle.load(myfile))

Теперь это, очевидно, не работает, потому что-1000 обычно не в начале одного из объектов, и pickle вызывает исключение и т. Д.эта идея, и я подозреваю, что она слишком сильно продвигает файл при определенных попытках чтения, и я мог пропустить несколько объектов.

Чтение файла с самого начала не вариант из-за его размера.

Есть идеи, чтобы это работало?Есть ли способ для pickle проверить, указывает ли курсор текущего файла на что-то похожее на объект или нет?

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Один из способов сделать что-то вроде этого:

import os, pickle, struct

myfile = open('/path/to/my/file', 'w+b')
myfile.write(struct.pack('L', 0)) # write a long of zeroes
index = []
for o in objects:
    index.append(myfile.tell())
    pickle.dump(o, myfile)
index_loc = myfile.tell()
pickle.dump(index, myfile)
myfile.seek(0, 0,  os.SEEK_SET)
myfile.write(struct.pack('L', index_loc))

Теперь у вас есть индексированный файл: при повторном открытии читайте местоположение индекса из начальных байтов, затем ищите это место и читайте индекс. После этого вы сможете получить доступ к любому объекту в файле в режиме произвольного доступа. (Конечно, вы можете обобщить это, указав, что индекс будет диктовать ключ объекта к расположению файла - что-то вроде ZODB для бедняка).

Или, конечно, вы можете использовать модуль shelve .

0 голосов
/ 07 апреля 2011

Сохранение в любом месте последовательности каждого приращения размера файла, получаемого в результате обновления файла

...