помилка UnicodeDecodeError: 'utf-8' кодек не може розшифрувати байт 0xff у позиції 0: недійсний початковий байт


163

https://github.com/affinelayer/pix2pix-tensorflow/tree/master/tools

Під час компіляції "process.py" на вищевказаному сайті сталася помилка.

 python tools/process.py --input_dir data --            operation resize --outp
ut_dir data2/resize
data/0.jpg -> data2/resize/0.png

Traceback (останній останній дзвінок):

File "tools/process.py", line 235, in <module>
  main()
File "tools/process.py", line 167, in main
  src = load(src_path)
File "tools/process.py", line 113, in load
  contents = open(path).read()
      File"/home/user/anaconda3/envs/tensorflow_2/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 0xff in position 0: invalid start byte

У чому причина помилки? Версія Python - це 3.5.2.

Відповіді:


194

Python намагається перетворити байтовий масив ( bytesякий вважається, що це закодована строка utf-8) в рядок unicode ( str). Цей процес, звичайно, є розшифровкою за правилами utf-8. При спробі цього він стикається з послідовністю байтів, яка не дозволена в закодованих рядками utf-8 (а саме це 0xff у позиції 0).

Оскільки ви не надали жодного коду, який ми могли б переглянути, ми могли лише здогадуватися про решту.

З сліду стека можна припустити, що ініціюючою дією було зчитування з файлу ( contents = open(path).read()). Я пропоную перечитати це в такий спосіб:

with open(path, 'rb') as f:
  contents = f.read()

Якщо bв специфікаторі режиму зазначено, open()що файл слід розглядати як бінарний, таким contentsчином залишатиметься a bytes. Жодна спроба декодування не відбудеться таким чином.


Я отримую помилку "ValueError: рядок режиму повинен починатися з одного з" r "," w "," a "або" U ", а не" br ""
Unnikrishnan,

3
@Unnikrishnan Добре, тоді використовуйте rb(я вважав, що порядок не має ніякого значення, але, здається, є, принаймні в деяких системах / версіях). Я відповідно змінив свою відповідь.
Альфе

57
byte 0xff in position 0також може означати, що файл закодований в UTF-16, тоді ви можете зробити це with open(path, encoding='utf-16') as f:замість цього
Микола R Kristiansen

Що робити, якщо насправді немає 0xffперсонажа в положенні 0? І це UTF-8закодовано.
Юліан Онофрей

Чистий '\xFF'символ буде закодований в UTF-8 як '\xC3\xBF'. UTF-8 кодує всі символи з набором MSB, використовуючи два символи. (Див. Висновок printf "\xff" | iconv -f latin1 -t utf-8 | xxdоболонки.) Дослівний '\xFF'на початку кодованої рядком UTF-8 є помилкою кодування (може називатися синтаксичною помилкою з точки зору UTF-8).
Альфа

83

Використовуючи це рішення, воно зніме (ігнорує) символи та поверне рядок без них. Використовуйте це лише в тому випадку, якщо вам потрібно позбавити їх, а не перетворити їх.

with open(path, encoding="utf8", errors='ignore') as f:

Використовуючи, errors='ignore' ви просто втратите кілька символів. але якщо ви не переймаєтесь ними, оскільки вони здаються зайвими символами, що виникають із-за поганого форматування та програмування клієнтів, що підключаються до мого серверного сокета. Тоді це просте безпосереднє рішення. довідник


6
Працює і для декодування (): contents = contents.decode('utf-8', 'ignore')Джерело: docs.python.org/3/howto/unicode.html#the-string-type
naaman

2
Має бути найкраща відповідь
Стейтем

найкраще рішення в моєму випадку використання :)
maestromusica

Коли ви говорите "втратити кілька символів", ти маєш на увазі, що файл з помилками не буде прочитаний? чи не буде прочитаний весь вміст цього файлу?
msoutopico

@msoutopico Оскільки він ігнорує помилки, то деякі кодування не будуть прочитані, які спричиняють проблеми. Але ніколи не стикався з будь-яким вмістом, який було пропущено під час читання. Тому в основному проблеми кодування ігноруються.
Нітіш Кумар Пал

23

Виникла проблема, схожа на цю, закінчилася використанням UTF-16 для декодування. мій код нижче.

with open(path_to_file,'rb') as f:
    contents = f.read()
contents = contents.rstrip("\n").decode("utf-16")
contents = contents.split("\r\n")

це сприймає вміст файлу як імпорт, але він повертає код у форматі UTF. звідти було б розшифровано та відокремлено рядками.


10
У Python 3 ви можете спростити це, скориставшись парам кодуванняwith open(path, encoding='utf-16') as f
Микола R Kristiansen

@NikolaiRKristiansen Я спробував використовувати ваш метод, але отримав помилку як TypeError: an integer is required (got type str). Чому? Обидва файли є двійковими та читаються як rb.
Богота

1
@Bogota Парам encodingмає сенс лише при читанні тексту. Відкиньте «b» з аргументу режиму і повторіть спробу. Детальніше читайте в документах: docs.python.org/3/library/functions.html#open
Микола Р. Крістіансен


15

Я натрапив на цю тему, коли зазнав тієї ж помилки, після деяких досліджень я можу підтвердити, що це помилка, яка виникає при спробі декодування файлу UTF-16 за допомогою UTF-8.

У UTF-16 перший characther (2 байти в UTF-16) - це позначка порядку байтів (BOM) , яка використовується як підказка декодування і не відображається як символ у декодованому рядку. Це означає, що перший байт буде або FE або FF, а другий, другий.

Сильно відредагований після того, як я дізнався справжню відповідь


Це закінчилося 2 години головного болю! Відкриття файлу з відкритим ("ім'я файлу", "r") у вигляді f: а потім надрукування його вмісту показує UTF-8, що невірно.
nulldroid

4

використовувати тільки

base64.b64decode(a) 

замість

base64.b64decode(a).decode('utf-8')

2
це працює, але просто для розуміння ви можете пояснити, чому будь ласка? :)
Ido

3

Якщо ви перебуваєте на mac, перевірте, чи є у вас прихований файл, .DS_Store. Після видалення файла моя програма працювала.


1

Перевірте шлях до файлу для читання. Мій код і надав мені помилки, поки я не змінив ім'я шляху до теперішнього робочого каталогу. Помилка:

newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

1

якщо ви отримуєте дані з послідовного порту, переконайтеся, що ви використовуєте правильну передачу (та інші конфігурації ): декодування за допомогою ( utf-8 ), але неправильний конфігурація призведе до тієї ж помилки

UnicodeDecodeError: 'utf-8' кодек не може розшифрувати байт 0xff в позиції 0: недійсний початковий байт

щоб перевірити конфігурацію послідовного порту при використанні Linux: stty -F /dev/ttyUSBX -a


1

Це просто означає, що для читання файлу вибрали неправильне кодування.

На Mac використовуйте, file -I file.txtщоб знайти правильне кодування. У Linux використовуйте file -i file.txt.


0

У мене така сама проблема під час обробки файлу, створеного з Linux. Виявляється, це було пов'язано з файлами, що містять знаки запитання ..


-1

У мене була подібна проблема.

Вирішили це:

import io

with io.open(filename, 'r', encoding='utf-8') as fn:
  lines = fn.readlines()

Однак у мене була інша проблема. Деякі файли html (у моєму випадку) не були utf-8, тому я отримав подібну помилку. Коли я виключив ці html-файли, все працювало безперебійно.

Тож, окрім виправлення коду, перевірте також файли, з яких ви читаєте, можливо, там справді є несумісність.


-4

Якщо можливо, відкрийте файл у текстовому редакторі та спробуйте змінити кодування на UTF-8. Інакше робіть це програмно на рівні ОС.


-4

У мене схожа проблема. Я намагаюся запустити приклад в tensorflow / models / aim_detection і зустріла те саме повідомлення. Спробуйте змінити Python3 на Python2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.