Запись двоичных данных в середину разреженного файла - PullRequest
2 голосов
/ 04 августа 2010

Мне нужно скомпилировать бинарный файл по частям, причем куски будут поступать в случайном порядке (да, это проект P2P)

def write(filename, offset, data) 
    file.open(filename, "ab")
    file.seek(offset) 
    file.write(data) 
    file.close()

Скажем, у меня есть запись 32 КБ (f, o, d) со смещением 1 МБ в файл, а затем еще одна запись 32 КБ (f, o, d) со смещением 0

Я получаю файл длиной 65 КБ (т. Е. Разрыв, состоящий из 0 с между 32 КБ - 1 МБ усекается / исчезает)

Я знаю, что это может показаться невероятно глупым вопросом, но я не могу понять это из режимов file.open (..)

Совет с благодарностью получен.

*** ОБНОВЛЕНИЕ

Мой метод написания P2P-частей закончился следующим образом (для тех, кто может извлечь из него какую-то ценность)

def writePiece(self, filename, pieceindex, bytes, ipsrc, ipdst, ts): 
    file = open(filename,"r+b")
    if not self.piecemap[ipdst].has_key(pieceindex):
        little = struct.pack('<'+'B'*len(bytes), *bytes) 
        # Seek to offset based on piece index 
        file.seek(pieceindex * self.piecesize)
        file.write(little)
        file.flush()
        self.procLog.info("Wrote (%d) bytes of piece (%d) to %s" % (len(bytes), pieceindex, filename))

    # Remember we have this piece now in case duplicates arrive 
    self.piecemap[ipdst][pieceindex] = True
    file.close()

Примечание: я также решил некоторые проблемы с порядком байтов, используя struct.pack, который мучил меня некоторое время.

Для всех, кто интересуется, проект, над которым я работаю, состоит в том, чтобы анализировать сообщения BT, захваченные непосредственно с провода.

Ответы [ 4 ]

6 голосов
/ 04 августа 2010
>>> import os
>>> filename = 'tempfile'
>>> def write(filename,data,offset):
...     try:
...         f = open(filename,'r+b')
...     except IOError:
...         f = open(filename,'wb')
...     f.seek(offset)
...     f.write(data)
...     f.close()
...
>>> write(filename,'1' * (1024*32),1024*1024)
>>> write(filename,'1' * (1024*32),0)
>>> os.path.getsize(filename)
1081344
4 голосов
/ 04 августа 2010

Вы открыли файл в режиме добавления ("a").Все записи идут в конец файла, независимо от вызовов seek().

0 голосов
/ 04 августа 2010

Мне кажется, что нет смысла пытаться собрать файл, пока все его части не найдутся. Почему бы не сохранить отдельные части, пока все не будут присутствовать, а затем записать их в окончательный файл по порядку? Это то, что делают большинство приложений P2P, AFAIK.

0 голосов
/ 04 августа 2010

Попробуйте использовать 'r + b' вместо 'ab'.

...