2015-05-14 13 views
5

Biorąc pod uwagę strumień bajtów (generator, plik itp.), W jaki sposób mogę odczytać pojedynczy kodowany znak utf-8?Odczytaj znak utf-8 ze strumienia bajtów

  • Ta operacja musi zużyć bajty tego znaku ze strumienia.
  • Ta operacja nie może zużywać żadnych bajtów strumienia, które przekraczają pierwszy znak.
  • Ta operacja powinna zakończyć się powodzeniem na dowolnym znaku Unicode.

mogłem podejść do tego przez walcowanie własną funkcję utf-8 dekodowania ale wolałbym, aby nie wyważać otwartych drzwi, ponieważ jestem pewien, że ta funkcja musi być już stosowane gdzie indziej do analizowania utf-8 sznurki.

Odpowiedz

2

Zawiń strumień w TextIOWrapper za pomocą encoding='utf8', a następnie zadzwoń pod numer .read(1).

Zakłada się, że zacząłeś od BufferedIOBase lub czegoś podobnego do kaczych (to znaczy, że ma on metodę read()). Jeśli masz generator lub iterator, być może będziesz musiał dostosować interfejs.

przykład:

from io import TextIOWrapper 

with open('/path/to/file', 'rb') as f: 
    wf = TextIOWrapper(f, 'utf-8') 
    wf._CHUNK_SIZE = 1 # Implementation detail, may not work everywhere 

    wf.read(1) # gives next utf-8 encoded character 
    f.read(1) # gives next byte 
+0

wykonuje 'TextIOWrapper' wykonywać żadnych buforujące (a tym samym zużycia bajtów przekroczeniu pierwszej postaci)? Jeśli wezmę plik 'f' i zawijam go' wrapped = TextIOWrapper (f, 'utf-8') ', wywołanie' wrapper.read (1) 'po którym następuje' f.read (1) 'odczytuje bajt, który jest znacznie dalej w strumieniu niż bajt bezpośrednio po znaku utf-8. – arcyqwerty

+0

@arcyqwerty: 'TextIOWrapper' czyta 2k bajtów na raz (' _CHUNK_SIZE'). Zużywa więcej bajtów niż to konieczne dla pierwszego znaku. – jfs

+0

Czy istnieje sposób, aby uzyskać surowe bajty z opakowania 'TextIOWrapper'? – arcyqwerty

Powiązane problemy