Кодек utf-8 не может декодировать байт 0x80

Я пытаюсь загрузить модель, обученную BVLC, и у меня возникает эта ошибка

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 110: invalid start byte

Я думаю, это из-за следующей функции (полный код)

  # Closure-d function for checking SHA1.
  def model_checks_out(filename=model_filename, sha1=frontmatter['sha1']):
      with open(filename, 'r') as f:
          return hashlib.sha1(f.read()).hexdigest() == sha1

Есть идеи, как это исправить?


person Ehab AlBadawy    schedule 24.04.2016    source источник
comment
Сообщение об ошибке довольно ясное. Либо у вас файл не в формате UTF8, либо он поврежден.   -  person Jongware    schedule 24.04.2016
comment
Вот что у меня получилось, когда я попытался напечатать f <_io.TextIOWrapper name='models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel' mode='r' encoding='utf8'>   -  person Ehab AlBadawy    schedule 24.04.2016
comment
Интересно. Так что же происходит, когда вы явно указываете кодировку файла? Что-то вроде open(filename, 'r', encoding='utf8')?   -  person Phil Cote    schedule 24.04.2016
comment
Я попытался изменить вторую строку этим with open(filename, 'r', encoding='utf8') as f:, но получил ту же ошибку   -  person Ehab AlBadawy    schedule 24.04.2016
comment
Нет, не сообщайте Python, что это UTF8. Если вы не уверены, что это должно быть, но Python сообщает вам, что это не действительный UTF8, а что-то еще. Откройте файл с помощью хорошего редактора кода и посмотрите, что внутри.   -  person Jongware    schedule 24.04.2016
comment
Я не могу, это файл .caffemodel, и там очень грязно, я использую vim. Я не думаю, что это должен быть читаемый файл.   -  person Ehab AlBadawy    schedule 24.04.2016
comment
Рад, что вы нашли полезными оба ответа! Обратите внимание, что вы можете отметить как принятый только один; выбор полностью зависит от вас, какой из них вы выберете. :-)   -  person Martijn Pieters    schedule 24.04.2016
comment
Да, спасибо, Martijn, я проголосовал за ваш ответ, так как это то, что я тоже ищу, но я сначала нашел сообщение DSM. В любом случае спасибо за вашу помощь :)   -  person Ehab AlBadawy    schedule 24.04.2016
comment
Я поправляюсь, Ракс. Мои извенения. Я не собирался вводить в заблуждение.   -  person Phil Cote    schedule 24.04.2016
comment
нп, спасибо Филу за помощь.   -  person Ehab AlBadawy    schedule 24.04.2016


Ответы (3)


Вы открываете файл, который не имеет кодировки UTF-8, в то время как кодировка по умолчанию для вашей системы установлена ​​на UTF-8.

Поскольку вы вычисляете хэш SHA1, вам следует читать данные как двоичные. Функции hashlib требуют передачи байтов:

with open(filename, 'rb') as f:
    return hashlib.sha1(f.read()).hexdigest() == sha1

Обратите внимание на добавление b в файловом режиме.

См. open() документацию:

mode - это необязательная строка, определяющая режим, в котором открывается файл. По умолчанию это 'r', что означает открытие для чтения в текстовом режиме. [...] В текстовом режиме, если кодировка не указана, используемая кодировка зависит от платформы: locale.getpreferredencoding(False) вызывается для получения текущей кодировки языкового стандарта. (Для чтения и записи необработанных байтов используйте двоичный режим и не указывайте кодировку.)

и из hashlib документации модуля:

Теперь вы можете кормить этот объект байтовыми объектами (обычно байтами) с помощью метода update ().

person Martijn Pieters    schedule 24.04.2016

Вы не указали открытие файла в двоичном режиме, поэтому f.read() пытается прочитать файл как текстовый файл в кодировке UTF-8, который, похоже, не работает. Но поскольку мы берем хеш байтов, а не строк, не имеет значения, какая кодировка или даже является ли файл текстовым: просто откройте его. , а затем прочтите его как двоичный файл.

>>> with open("test.h5.bz2","r") as f: print(hashlib.sha1(f.read()).hexdigest())
Traceback (most recent call last):
  File "<ipython-input-3-fdba09d5390b>", line 1, in <module>
    with open("test.h5.bz2","r") as f: print(hashlib.sha1(f.read()).hexdigest())
  File "/home/dsm/sys/pys/Python-3.5.1-bin/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 10: invalid start byte

но

>>> with open("test.h5.bz2","rb") as f: print(hashlib.sha1(f.read()).hexdigest())
21bd89480061c80f347e34594e71c6943ca11325
person DSM    schedule 24.04.2016

Поскольку ни в документации, ни в коде src нет ни одной подсказки, я не знаю почему, но использование символа b (я думаю, для двоичного кода) полностью работает (tf-version: 1.1.0):

image_data = tf.gfile.FastGFile(filename, 'rb').read()

Подробнее см. а>

person 4F2E4A2E    schedule 13.05.2017