python utf-8 - SIG BOM в середине файла при добавлении к концу

недавно я заметил, что Python ведет себя таким неочевидным образом при добавлении к файлу с помощью utf-8-sig кодировка. См. ниже:

>>> import codecs, os
>>> os.path.isfile('123')
False
>>> codecs.open('123', 'a', encoding='utf-8-sig').write('123n')
>>> codecs.open('123', 'a', encoding='utf-8-sig').write('123n')

в файл попадает следующий текст:

<BOM>123
<BOM>123

разве это не ошибка? Это так нелогично. Может кто-нибудь объяснить мне, почему это было сделано так? Почему им не удалось добавить BOM только тогда, когда файл не существует и должен быть создан?

1 ответов


нет, это не ошибка; это вполне нормальное, ожидаемое поведение. Кодек не может определить, сколько уже было записано в файл; вы можете использовать его для добавления к предварительно созданному, но пустой например. Файл не будет новым,но и не будет содержать спецификации.

тогда есть другие случаи использования, когда кодек используется в потоке или bytestring (например, не с codecs.open()) где нет файл для тестирования или где разработчик всегда хочет применить спецификацию в начале вывода.

использовать только utf-8-sig на новая файл; кодек будет всегда напишите BOM вне когда вы используете его.

если вы работаете непосредственно с файлами, вы можете проверить для начала самостоятельно; используйте utf-8 вместо этого и напишите спецификацию вручную, которая просто закодирована U+FEFF НУЛЕВАЯ ШИРИНА БЕЗ ПЕРЕРЫВА:

import io

with io.open(filename, 'a', encoding='utf8') as outfh:
    if outfh.tell() == 0:
        # start of file
        outfh.write(u'\ufeff')

я использовал более новый io.open() вместо codecs.open(); io - это новый фреймворк ввода-вывода, разработанный для Python 3, и более надежный, чем codecs для обработки закодированных файлов, по моему опыту.

обратите внимание, что спецификация UTF-8 практически бесполезна. UTF-8 не имеет переменного порядка байтов и один Метку Порядка Следования Байтов. UTF-16 или UTF-32, С другой стороны, могут быть написаны с одним из двух различных порядков байтов, поэтому необходима спецификация.

спецификация UTF-8 в основном используют продукты Microsoft для автоматического определения кодировки файла (например,не одно из устаревших кодовых страниц).