Python: запись и чтение блоков двоичных данных в файл



Я работаю над сценарием, в котором он разбивает другой скрипт python на блоки и использует pycrypto для шифрования блоков (все это я успешно сделал до сих пор), теперь я сохраняю зашифрованные блоки в файл, чтобы дешифровщик мог прочитать его и выполнить каждый блок. Конечным результатом шифрования является список двоичных выходов (что-то вроде blocks=[b'xa1rxa594x92zxf8x16xaa',b'xfbIxfdqx|xcdxdbx1bxb3',etc...]).



При записи выходных данных в файл все они заканчиваются в одной гигантской строке, так что при чтении файла все байты возвращаются в одну гигантскую строку вместо каждого элемента из исходного списка. Я также попытался преобразовать байты в строку и добавить 'n' в конце каждого из них, но проблема заключается в том, что мне все еще нужны байты, и я не могу понять, как отменить строку, чтобы получить исходный байт.



Чтобы подытожить это, я ищу либо: записать каждый двоичный элемент в отдельную строку в файле, чтобы я мог легко прочитать данные и использовать их при расшифровке, либо я мог бы перевести данные в string и в decrpytion отменить строку, чтобы получить обратно исходные двоичные данные.



Вот код для записи в файл:



    new_file = open('C:/Python34/testfile.txt','wb')
for byte_item in byte_list:
# This or for the string i just replaced wb with w and
# byte_item with ascii(byte_item) + 'n'
new_file.write(byte_item)
new_file.close()


И для чтения файла:



    # Or 'r' instead of 'rb' if using string method
byte_list = open('C:/Python34/testfile.txt','rb').readlines()
535   3  

3 ответов:

Файл - это поток байтов без какой-либо подразумеваемой структуры. Если вы хотите загрузить список двоичных двоичных объектов, то вам следует сохранить некоторые дополнительные метаданные для восстановления структуры, например, вы можете использовать формат netstring:

#!/usr/bin/env python
blocks = [b'\xa1\r\xa594\x92z\xf8\x16\xaa', b'xfbI\xfdqx|\xcd\xdb\x1b\xb3']

# save blocks
with open('blocks.netstring', 'wb') as output_file:
    for blob in blocks:
        # [len]":"[string]","
        output_file.write(str(len(blob)).encode())
        output_file.write(b":")
        output_file.write(blob)
        output_file.write(b",")

Прочитайте их обратно:

#!/usr/bin/env python3
import re
from mmap import ACCESS_READ, mmap

blocks = []
match_size = re.compile(br'(\d+):').match
with open('blocks.netstring', 'rb') as file, \
     mmap(file.fileno(), 0, access=ACCESS_READ) as mm:
    position = 0
    for m in iter(lambda: match_size(mm, position), None):
        i, size = m.end(), int(m.group(1))
        blocks.append(mm[i:i + size])
        position = i + size + 1 # shift to the next netstring
print(blocks)

В качестве альтернативы вы можетерассмотреть формат BSON для ваших данных илиформат ascii armor .

Я думаю, что вы ищете byte_list=open('C:/Python34/testfile.txt','rb').read()

Если вы знаете, сколько байт занимает каждый элемент, вы можете использовать read(number_of_bytes) для обработки одного элемента за один раз.

read() вы прочитаете весь файл, но затем вам придется декодировать весь этот список байтов в соответствующие элементы.

В общем, поскольку вы используете Python 3, Вы будете работать с bytes объекты (которые являются неизменяемыми) и/или bytearray объекты (которые изменчивы).

Пример:

b1 = bytearray('hello', 'utf-8')
print b1

b1 += bytearray(' goodbye', 'utf-8')
print b1

open('temp.bin', 'wb').write(b1)

#------

b2 = open('temp.bin', 'rb').read()
print b2

Вывод:

bytearray(b'hello')
bytearray(b'hello goodbye')
b'hello goodbye'

Comments

    Ничего не найдено.