Метод Python для хранения списка байтов в сетевом порядке (с прямым порядком байтов) в файл (с прямым порядком байтов) - PullRequest
4 голосов
/ 04 августа 2010

Моя текущая задача - проанализировать данные tcpdump, которые включают в себя сообщения P2P, и у меня возникли проблемы с частичными данными, которые я получаю и записываю в файл на моем компьютере с архитектурой x86.Я подозреваю, что у меня есть простая проблема с байтами, которые я записываю в файл.

У меня есть список байтов, содержащих фрагмент видео P2P, прочитанный и обработанный с использованием пакета BTW для python-pcapy.

bytes = [14, 254, 23, 35, 34, 67, etc... ]

Я ищу способ сохранить эти байты, которые в настоящее время хранятся в списке в моем приложении Python, в файл.

В настоящее время я пишу части следующим образом:

def writePiece(self, filename, pieceindex, bytes, ipsrc, ipdst, ts): 
    file = open(filename,"ab")
    # Iterate through bytes writing them to a file if don't have piece already 
    if not self.piecemap[ipdst].has_key(pieceindex):
        for byte in bytes: 
            file.write('%c' % byte)
        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

    # TODO: Collect stats 
    file.close()

Как вы можете видеть из цикла for, я записываю байты в файл в том же порядке, как я их обрабатываю по проводам.(т. е. сетевой или порядок с прямым порядком байтов).

Достаточно сказать, что видео, являющееся полезной нагрузкой фрагментов, плохо воспроизводится в VLC :-D

Я думаю, что мне нужно преобразовать их в порядок байтов с прямым порядком байтов, но я неуверен, что лучший способ подойти к этому в Python.

ОБНОВЛЕНИЕ

Решение, которое сработало для меня (написание 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()

Ключ кРешением было использование структурного модуля Python, как и предполагалось, в частности:

    little = struct.pack('<'+'B'*len(bytes), *bytes) 

Спасибо тем, кто ответил полезными предложениями.

Ответы [ 3 ]

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

Чтобы сэкономить некоторую работу, вы можете использовать bytearray (Python 2.6 и более поздние версии):

b = [14, 254, 23, 35]
f = open("file", 'ab')
f.write(bytearray(b))

Это все преобразования ваших значений 0-255.в байты без необходимости всего цикла.

Я не могу понять, в чем ваша проблема, без дополнительной информации.Если данные на самом деле являются побайтовыми, то порядок байтов не является проблемой, как говорили другие.

(Кстати, использование bytes и file в качестве имен переменных не очень хорошо, поскольку они скрываютвстроенные модули с таким же именем).

1 голос
/ 22 августа 2010

Вы также можете использовать array.array :

from array import array
f.write(array('B', bytes))

вместо

f.write(struct.pack('<'+'B'*len(bytes), *bytes))

что немного прибрано

f.write(struct.pack('B' * len(bytes), *bytes))
# the < is redundant; there is NO ENDIANNESS ISSUE

который, если len (байты) "большой", может быть лучше, чем

f.write(struct.pack('%dB' % len(bytes), *bytes)) 
0 голосов
/ 04 августа 2010

На этот вопрос ранее можно было ответить в Ошибка файла Python с преобразованием в обратный порядок .

...