Предположим, у меня был ASCII-файл (так называемый «test.txt»), как это:посимвольно в UTF8 файле
A B C D
X Y Z
^ EOF, no CR after the 'Z'...
В Python, я мог прочитать последний байт (последний символ) что-то вроде этого :
with open('test.txt', 'r') as f:
f.seek(-1, os.SEEK_END)
ch=f.read(1)
Я мог бы укоротить последние 3 символов, как так:
with open('test.txt', 'r') as f:
f.seek(-3, os.SEEK_END)
f.truncate()
Теперь предположим, что у меня есть второй файл (так называемый «тэ st.utf ') в кодировке UTF-8 со следующими одно- и многобайтовые символы:
A B C D
Ⓐ Ⓑ Ⓒ Ⓓ
Z Ⓩ
Я знаю, как читать весь файл (с использованием кодеков):
>>> f=codecs.open('/tmp/test.utf', 'r', 'utf-8')
>>> L=f.readlines()
>>> L
[u'A B C D\n', u'\u24b6 \u24b7 \u24b8 \u24b9\n', u'Z \u24cf']
И я полагаю, Я мог бы использовать Deque из модуля коллекции, чтобы получить последние N символов:
>>> from collections import deque
>>> with codecs.open(fn,'r+', encoding) as f:
... last_3=deque(f.read(),3)
>>> last_3
deque([u'Z', u' ', u'\u24cf'], maxlen=3)
Так вопрос: есть ли в любом случае (что мне не хватает), где я могу логически шаг назад через символ файла UTF-8 логическим чара cter БЕЗ чтения всего файла в память? С ASCII это легко; просто найдите один байт ближе к началу файла. Но в UTF-8 Ⓩ
составляет 3 байта (E2 93 8F
) и Z
- всего один байт.
Напомним, что UTF-8 имеет переменную ширину - от 1 до 4 байтов на символ. Если вы не начинаете с самого начала, я думаю, что нет способа узнать, какие границы символов ...
В самом деле, где-то в Интернете вы можете найти электронную почту Кена Томпсона, где он объяснил, что это половина мотивация UTF-8 в дизайне: вы можете синхронизировать с любой точки в потоке, вперед или назад, не читая не более чем один символ. (Другая половина состоит в том, что байт, который представляет собой печатный символ ASCII, не может быть частью представления любого другого персонажа.) – abarnert
... или, может быть, вы не можете его найти. По крайней мере, я не могу. Лучшее, что я мог найти, это [документ Plan 9 на UTF-8] (http://plan9.bell-labs.com/sys/doc/utf.pdf), который он соавтор. – abarnert
@abarnert: это то, что вы ищете? http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt, примерно наполовину вниз, цитирует Кен Томпсон: «6) Должно быть возможно найти начало персонажа эффективно начиная с произвольного местоположения в потоке байтов ». – Neil