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.

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.


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


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.


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


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ź


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


3

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


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

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


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.


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.


-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ść.


-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.


-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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.