#python #codepages
Вопрос:
В настоящее время я пытаюсь создать код для алгоритма сжатия данных. Моя цель состоит в том, чтобы взять файл и прочитать его, преобразовать в двоичный эквивалент, а затем сохранить его в выходной текстовый файл.
Например: Допустим, мой ввод — «Привет, мир».,
тогда я хочу, чтобы в моем выводе было «0100100001100101011011000110110001101111001000000101011101101111011110111100110110001100100».
Этот код успешно выполняет это для большинства сообщений. Однако у меня есть файл с необходимым байтом информации «10000001». В CP-1252 это соответствует неопределенному символу.
Есть ли 8-разрядная кодовая страница, которую я могу использовать в строке 9, символ 51 моего кода, который использует все 256 возможных кодов, чтобы избежать этой ошибки?
from datetime import datetime
now = datetime.now()
#makes a file with a unique timestamp in the name
stamp = now.strftime("%H%M%S")
f = open("requests" str(stamp) ".txt", "w")
#opens desired input file in read mode
text_file = open("videointxt", mode="r", encoding=None)
^
#read whole file to a string
data = text_file.read()
#takes the message converts it to its binary equivakent, and then writes it to the output file
res = ''.join(format(ord(i), '08b') for i in data)
print(res, file=f)
f.close
Комментарии:
1. Ваш вывод представляет собой строку обычных ASCII
"1"
s и"0"
s. Неясно, где у вас возникли проблемы с наборами символов.2. Просто хочу отметить,
encoding=None
что декодирование не «отключается» при чтении из файла. Он просто указываетopen
использовать кодировку по умолчанию вашей платформы, которая может не совпадать с тем, что на самом деле используется файлом для кодирования вложенного текста. Кроме того, если вы хотите прочитать необработанные байты, откройте файл в двоичном режиме (mode='rb'
) и интерпретируйте байты самостоятельно.
Ответ №1:
Ваша проблема не в кодовой странице как таковой. Ваша проблема в том, что вы пытаетесь интерпретировать двоичную информацию в виде символов. В python3.x строки являются Юникодом. Чтобы Python мог считывать данные в виде строки, ему необходимо знать отображение значений в символы, т. е. кодировку. Если вы просто хотите загрузить необработанные данные без их интерпретации, вы, вероятно, захотите предварительно выполнить чтение байта и пропустить передачу кодировки.
- text_file = open("videointxt", mode="r", encoding=None)
text_file = open("videointxt", mode="rb")
Переменная text_file
теперь будет иметь тип байтов вместо типа строки, поэтому вам нужно будет изменить способ взаимодействия с ней, но это означает, что вам не нужно возиться с кодировками, пока вы не решите, как вы хотите отображать информацию на экране.
Лично я бы предложил отображать выходные данные в шестнадцатеричном формате, а не в двоичном.
Пожалуйста, обратите внимание, что текстовые данные на диске уже имеют двоичный формат. При хранении двоичного эквивалента на диске нет никаких преимуществ для хранения. Процесс преобразования символов в двоичный код и записи на диск является обратным тому, что произошло, когда файл был прочитан с самого начала.
Как говорит @chepner, ваш код создает строку из символов » 0 » и «1», что увеличит общий размер файла в 8 раз.
Если вы работаете на терминале Linux, вы можете убедиться в этом сами:
# my_script.py
with open('tmp', 'rb') as f:
data = file.read()
print(''.join(format(i, '08b') for i in data))
$ echo -n 'a' > tmp
$ xxd -b tmp
00000000: 01100001 a
$ python my_script.py > tmp
$ xxd -b tmp
00000000: 00110000 00110001 00110001 00110000 00110000 00110000 011000
00000006: 00110000 00110001 01
Обратите внимание, как вы увеличили размер файла с 1 байта до 8, потому что вместо хранения » a «в виде 1 байта данных вы сохраняете 8 экземпляров символов «0» и «1».
Комментарии:
1. Это очень плохой способ работы с текстом. Байты будут непригодны для использования до тех пор, пока они не будут преобразованы в текст. Когда это произойдет, проблема будет точно такой же — необходимо указать кодировку. Если только текст не отображается в виде шестнадцатеричного значения, которое все еще является своего рода кодировкой. Если кодировка файла известна, его можно использовать
open
как в любом другом месте, так и в любом другом2. @PanagiotisKanavos Ты на 100% прав. Моя интерпретация операции заключается в том, что они хотят прочитать файл, «преобразовать его в двоичный файл» и записать его обратно на диск. Я думаю, что основная проблема заключается не в том, читается ли строка как символы или двоичный файл, а в том, что строковые данные на диске еще не являются двоичным форматом. Я хотел бы услышать любые предложения о том, как я могу лучше это объяснить. 🙂
3. Основная причина, по которой я хотел записать формат ASCII исходного двоичного файла, заключалась в том, чтобы затем python произвел битовые манипуляции с теперь выведенным файлом, а затем перекомпилировал теперь обработанный двоичный файл ASCII обратно в обычный двоичный файл. Этот шаг для записи входного файла в двоичный файл ASCII предназначен для алгоритма сжатия данных для его чтения. Тем не менее, я думаю, что если у меня просто будет код, просто прочитайте двоичный файл, разбейте его на более мелкие фрагменты, поместите фрагменты в словарь, то я думаю, что смогу сделать то же самое без необходимости преобразования в ASCII-двоичный шаг. Спасибо за помощь!