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()
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