Записывая двоичные файлы в Python 3, почему я не получаю шестнадцатеричное представление 9,10 и 13?

1

Im записывая байты 9, 10 и 13 в файл в двоичном режиме, но они отображаются как \t, \n, \r. Я не понимаю, почему.

# opening file in binary write mode 
with open("C://Users//lenovo//Desktop//sample.txt",'bw') as mm:
    for i in range(17):
        mm.write(bytes([i]))


#opening file in binary read mode
with open("C://Users//lenovo//Desktop//sample.txt",'br') as mp:
    for i in mp:
        print(i)

выход:-

b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n'
b'\x0b\x0c\r\x0e\x0f\x10'
  • 4
    потому что python заменяет известные символьные буквы своим шестнадцатеричным представлением: \ n == \ x0a, \ t == \ x09 и т. д., когда вы их распечатываете - см. asciitable.com . Откройте файл в hex-редакторе, и вы действительно увидите, что в нем 0x10 ...
  • 0
    Возможный дубликат Как правильно преобразовать байты в шестнадцатеричную строку в Python 3? ... не могу найти обман, где я читаю материал \ t == \ 0x09 на распечатке некоторое время назад.
Теги:
python-3.x

1 ответ

0

Расширение первого комментария Патрика:

Фактически вы получаете именно то, что ожидаете получить. Проблема в том, что Python не печатает их так, как вы ожидаете.

Символ табуляции в ASCII равен 0x09. Новая 0x0a - 0x0a. Возврат каретки равен 0x0d. Поэтому Python печатает их с использованием экранированных символов, которые обычно используются для часто используемых символов: \t \n \r.

Другие значения, которые вы использовали, 0x00 и 0x01 и т.д., Не имеют таких ярлыков, поэтому Python печатает их в шестнадцатеричном формате, как ожидалось.

Также обратите внимание, что вы читаете по одной строке за раз (for я in mp:, поэтому, когда Python видит новую строку, она перестает читать первую строку там, а остальная часть файла заканчивается во второй строке.

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

Чтобы прочитать фрагменты с равным размером файла, мы просто используем метод read объекта файла. Я думаю, что его, вероятно, наиболее читаемо оставить 0x out, но вставить пробелы между байтами. Мы можем легко сделать это, используя форматирование строк.

bytes_per_line = 8

with open(r'C:\Users\lenovo\Desktop\sample.txt', 'br') as mp:
    while True:
        b = mp.read(bytes_per_line)
        if not b:
            break
        fmt = ('{:02x} ' * len(b))[:-1]
        print(fmt.format(*b))

Заметки:

  • r перед именем файла делает его необработанной строкой, поэтому нам не нужно удвоить обратную косую черту
  • метод read будет читать bytes_per_line (8) за раз, за исключением EOF
  • Вблизи EOF мы можем получить менее 8 байт, в зависимости от размера файла
  • В EOF мы получаем пустую строку и выходим из цикла
  • fmt - это что-то вроде '{:02x} {:02x} {:02x} {:02x}', один спецификатор формата на байт
  • [:-1] удаляет последний символ - читайте о разрезании
  • Мы используем fmt с методом format чтобы применить его к *b
  • *b означает передать байты b как отдельные аргументы, соответствующие спецификаторам формата в fmt
  • 0
    Судя по фрагментам кода OP, он не так опытен в Python, как вы. Я бы порекомендовал добавить комментарии, чтобы помочь ему понять.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню