błąd UnicodeDecodeError: kodek 'utf-8' nie może zdekodować bajtu 0xff na pozycji 0: nieprawidłowy bajt początkowy

162

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

Wystąpił błąd podczas kompilowania pliku „process.py” w powyższej witrynie.

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

Traceback (ostatnie ostatnie połączenie):

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

Jaka jest przyczyna błędu? Wersja Pythona to 3.5.2.

ciasto
źródło

Odpowiedzi:

194

Python próbuje przekonwertować tablicę bajtów ( bytesktóra zakłada, że ​​jest łańcuchem zakodowanym w utf-8) na ciąg znaków Unicode ( str). Ten proces jest oczywiście dekodowaniem zgodnie z regułami utf-8. Kiedy próbuje tego, napotyka sekwencję bajtów, która nie jest dozwolona w łańcuchach zakodowanych w utf-8 (mianowicie ten 0xff na pozycji 0).

Ponieważ nie podałeś żadnego kodu, na który moglibyśmy spojrzeć, mogliśmy tylko zgadnąć, co do reszty.

Ze śladu stosu możemy założyć, że akcją wyzwalającą był odczyt z pliku ( contents = open(path).read()). Proponuję przepisać to w następujący sposób:

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

Że bw specyfikatorze trybu w open()stanach, że plik ma być traktowany jako binarny, więc contentspozostanie bytes. W ten sposób nie nastąpi próba dekodowania.

Alfe
źródło
Pojawia się błąd „ValueError: ciąg trybu musi zaczynać się od jednego z„ r ”,„ w ”,„ a ”lub„ U ”, a nie„ br ””
Unnikrishnan
3
@Unnikrishnan Ok, więc użyj rb(myślałem, że kolejność nie ma znaczenia, ale wydaje się, że jest, przynajmniej w niektórych systemach / wersjach). Odpowiednio zmieniłem odpowiedź.
Alfe
57
byte 0xff in position 0może również oznaczać, że plik jest zakodowany w UTF-16, a następnie można zrobić with open(path, encoding='utf-16') as f:zamiast
Nikolai R Kristiansen
A co, jeśli 0xffna pozycji nie ma żadnego znaku 0? I to jest UTF-8zakodowane.
Iulian Onofrei
Czysty '\xFF'znak zostanie zakodowany w UTF-8 jako '\xC3\xBF'. UTF-8 koduje wszystkie znaki za pomocą zestawu MSB przy użyciu dwóch znaków. (Zobacz dane wyjściowe printf "\xff" | iconv -f latin1 -t utf-8 | xxdw powłoce). Dosłowne słowo '\xFF'na początku łańcucha zakodowanego w UTF-8 jest błędem kodowania (można go nazwać błędem składni w terminologii UTF-8).
Alfe
83

Użyj tego rozwiązania, aby usunąć (zignorować) znaki i zwrócić ciąg bez nich. Używaj tego tylko wtedy, gdy potrzebujesz ich rozebrać, a nie przerobić.

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

Korzystanie errors='ignore' Po prostu stracisz kilka znaków. ale jeśli nie przejmujesz się nimi, ponieważ wydają się być dodatkowymi znakami pochodzącymi z niewłaściwego formatowania i programowania klientów łączących się z moim serwerem gniazd. Wtedy jest to łatwe i bezpośrednie rozwiązanie. odniesienie

Nitish Kumar Pal
źródło
6
Działa również dla decode (): contents = contents.decode('utf-8', 'ignore')Źródło: docs.python.org/3/howto/unicode.html#the-string-type
naaman
2
Powinna być najlepszą odpowiedzią
Statham
najlepsze rozwiązanie w moim przypadku :)
maestromusica
Kiedy mówisz „stracić kilka znaków”, czy masz na myśli, że plik z błędami nie zostanie odczytany? lub że nie cała zawartość tego pliku zostanie odczytana?
msoutopico
@msoutopico Ponieważ ignoruje błędy, niektóre kodowania nie zostaną odczytane, które powodują problemy. Ale nigdy nie spotkałem żadnej treści, która została pominięta podczas czytania. Więc zasadniczo kwestie ekodowania są ignorowane.
Nitish Kumar Pal
23

Miałem problem podobny do tego, Skończyło się na używaniu UTF-16 do dekodowania. mój kod jest poniżej.

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

spowoduje to pobranie zawartości pliku jako importu, ale zwróci kod w formacie UTF. stamtąd był dekodowany i oddzielany liniami.

tattmoney76
źródło
10
W Pythonie 3 możesz to uprościć, używając parametru kodowaniawith open(path, encoding='utf-16') as f
Nikolai R Kristiansen
@NikolaiRKristiansen Próbowałem użyć twojej metody, ale pojawił się błąd jako TypeError: an integer is required (got type str). Czemu? Oba pliki są binarne i czytane jako rb.
Bogota
1
@Bogota Parametr encodingma sens tylko podczas czytania tekstu. Usuń „b” z argumentu mode i spróbuj ponownie. Przeczytaj więcej w dokumentacji: docs.python.org/3/library/functions.html#open
Nikolai R Kristiansen
19

Aby rozwiązać problem, użyj formatu kodowania ISO-8859-1 .

Ramineni Ravi Teja
źródło
1
W końcu wylądowałem na tym po wypróbowaniu ponad 10 innych kodowań!
Rexcirus
15

Natknąłem się na ten wątek, gdy cierpię na ten sam błąd, po przeprowadzeniu badań, które mogę potwierdzić, jest to błąd, który pojawia się podczas próby dekodowania pliku UTF-16 za pomocą UTF-8.

W przypadku UTF-16 pierwszy znak (2 bajty w UTF-16) to Byte Order Mark (BOM) , który jest używany jako wskazówka dekodowania i nie pojawia się jako znak w dekodowanym ciągu. Oznacza to, że pierwszy bajt będzie FE lub FF, a drugi to drugi.

Mocno zredagowane po tym, jak znalazłem prawdziwą odpowiedź

Peter Ogden
źródło
To zakończyło 2 godziny bólu głowy! Otwarcie pliku za pomocą polecenia open („filename”, „r”) jako f: i wydrukowanie jego zawartości pokazuje UTF-8, co jest błędne.
nulldroid
4

tylko do użytku

base64.b64decode(a) 

zamiast

base64.b64decode(a).decode('utf-8')
pradeep karunathilaka
źródło
2
to działa, ale żeby zrozumieć, czy możesz wyjaśnić, dlaczego, proszę? :)
Ido Bleicher
3

Jeśli używasz komputera Mac, sprawdź, czy nie masz ukrytego pliku, .DS_Store. Po usunięciu pliku mój program działał.

Juan Navarrete
źródło
1

Sprawdź ścieżkę do pliku do odczytania. Mój kod ciągle dawał mi błędy, dopóki nie zmieniłem nazwy ścieżki na obecny katalog roboczy. Błąd:

newchars, decodedbytes = self.decode(data, self.errors)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Rex131xO
źródło
1

jeśli otrzymujesz dane z portu szeregowego, upewnij się, że używasz właściwej szybkości transmisji (i innych konfiguracji): dekodowanie przy użyciu ( utf-8 ), ale zła konfiguracja wygeneruje ten sam błąd

UnicodeDecodeError: kodek „utf-8” nie może zdekodować bajtu 0xff na pozycji 0: nieprawidłowy bajt początkowy

aby sprawdzić konfigurację portu szeregowego w systemie Linux użyj: stty -F /dev/ttyUSBX -a

Saif Faidi
źródło
1

Oznacza to po prostu, że do odczytania pliku wybrano niewłaściwe kodowanie.

Na komputerze Mac użyj, file -I file.txtaby znaleźć prawidłowe kodowanie. W systemie Linux użyj file -i file.txt.

Minh Triet
źródło
0

Mam ten sam problem podczas przetwarzania pliku wygenerowanego z Linuksa. Okazuje się, że było to związane z plikami zawierającymi znaki zapytania.

Wim Folkerts
źródło
-1

Miałem podobny problem.

Rozwiązany przez:

import io

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

Jednak miałem inny problem. Niektóre pliki html (w moim przypadku) nie były w formacie utf-8, więc otrzymałem podobny błąd. Kiedy wykluczyłem te pliki html, wszystko działało gładko.

Więc oprócz naprawiania kodu, sprawdź także pliki, z których czytasz, może rzeczywiście jest tam niezgodność.

Kostas Tsiligkiris
źródło
-4

Jeśli to możliwe, otwórz plik w edytorze tekstu i spróbuj zmienić kodowanie na UTF-8. W przeciwnym razie zrób to programowo na poziomie systemu operacyjnego.

Manoj Joshi
źródło
-4

Mam podobny problem. Próbuję uruchomić przykład w tensorflow / models / objective_detection i otrzymałem ten sam komunikat. Spróbuj zmienić Python3 na Python2

user8665083
źródło