2014-07-07 12 views
11

Muszę przeczytać plik tekstowy w Pythonie. Kodowanie pliku jest:UnicodeDecodeError w Pythonie podczas czytania pliku, jak zignorować błąd i przejść do następnego wiersza?

file -bi test.csv 
text/plain; charset=us-ascii 

Ten plik jest przez stronę trzecią, i dostać nowy codziennie, więc nie chciałbym go zmienić. Plik nie ma znaków ASCII, takich jak na przykład. Muszę czytać linie używając Pythona i mogę pozwolić sobie na zignorowanie linii, która ma nie-ascii.

Mój problem polega na tym, że kiedy czytam plik w Pythonie, otrzymuję UnicodeDecodeError po osiągnięciu linii, w której istnieje znak inny niż ascii, i nie mogę odczytać pozostałej części pliku.

Czy istnieje sposób, aby tego uniknąć. Jeśli spróbuję tego:

fileHandle = codecs.open("test.csv", encoding='utf-8'); 
try: 
    for line in companiesFile: 
     print(line, end=""); 
except UnicodeDecodeError: 
    pass; 

to po osiągnięciu błędu pętla for kończy się i nie mogę odczytać pozostałej części pliku. Chcę pominąć linię, która powoduje błąd i iść dalej. Wolałbym nie wprowadzać żadnych zmian w pliku wejściowym, jeśli to możliwe.

Czy jest jakiś sposób to zrobić? Dziękuję bardzo.

+0

Dlaczego używasz 'codecs.open()' w Pythonie 3? 'open()' obsługuje UTF-8 ** w porządku **. –

+0

Próbowałem również używać open, pojawia się ten sam błąd – Chicoscience

+0

Czy wiesz, co naprawdę używa kodowanie pliku? Z pewnością nie jest to "us-ascii", jak pokazano na wyjściu 'file', ponieważ zawiera znaki spoza ASCII. – dano

Odpowiedz

24

Twój plik nie wygląda na kodowanie UTF-8. Podczas otwierania pliku należy używać poprawnego kodeka.

Ty może powiedzieć open() jak traktować błędy dekodowania, za pomocą słowa kluczowego errors:

błędy to opcjonalny ciąg znaków, który określa, w jaki sposób są kodowania i dekodowania błędy mają być obsługiwane, to nie może być stosowany w trybie binarnym. Dostępnych jest wiele standardowych procedur obsługi błędów, jednak każda nazwa obsługi błędów, która została zarejestrowana pod numerem codecs.register_error(), jest również ważna. Standardowe nazwy są:

  • 'strict' podnieść ValueError wyjątek, jeśli wystąpi błąd kodowania. Domyślna wartość None ma taki sam efekt.
  • 'ignore' ignoruje błędy. Pamiętaj, że ignorowanie błędów kodowania może prowadzić do utraty danych.
  • 'replace' powoduje wstawienie znacznika zastępczego (takiego jak "?") W przypadku nieprawidłowo sformatowanych danych.
  • 'surrogateescape' będzie reprezentować wszystkie niepoprawne bajty jako punkty kodowe w obszarze prywatnym użytkowania Unicode w zakresie od U + DC80 do U + DCFF. Te prywatne punkty kodowe zostaną następnie zwrócone do tych samych bajtów, gdy podczas zapisywania danych używany jest moduł obsługi błędów surrogateescape. Jest to przydatne do przetwarzania plików w nieznanym kodowaniu.
  • 'xmlcharrefreplace' jest obsługiwany tylko podczas zapisu do pliku. Znaki nieobsługiwane przez kodowanie są zastępowane odpowiednimi znakami XML o numerze &#nnn;.
  • 'backslashreplace' (również obsługiwane tylko podczas pisania) zastępuje nieobsługiwane znaki za pomocą sekwencji uśpionych w języku Python.

Otwieranie pliku z 'ignore' lub 'replace' następnie pozwala odczytać pliku bez wyjątków są podniesione.

+0

Starałem się znaleźć alternatywne rozwiązanie łapiąc same wyjątki dekodowania. Niestety pojawia się (przynajmniej w Pythonie 2), że dekodowanie następuje * przed wykryciem * końca linii, więc nie uzyskujesz spójnych wyników - możesz stracić więcej niż jedną linię, lub możesz zostać zawieszony na tym samym buforze na zawsze. –

+0

To nie działa w python 2.x. –

+1

@AndrejGajduk: nie, nie ma i nigdy nie było zamierzone. Pytanie dotyczy Pythona 3. W Pythonie 2 * możesz * używać 'io.open()' jednak (co jest w zasadzie tą samą funkcją). –