Когда вы сохраняете файл как UTF-16, каждое значение составляет два байта.Разные компьютеры используют разные порядки байтов.Некоторые ставят самый старший байт первым, другие ставят младший байт первым.Unicode резервирует специальную кодовую точку (U + FEFF), называемую меткой порядка байтов (BOM).Когда программа записывает файл в UTF-16, она помещает эту специальную кодовую точку в начало файла.Когда другая программа читает файл UTF-16, она знает, что там должна быть спецификация.Сравнивая фактические байты с ожидаемой спецификацией, он может определить, использует ли считыватель тот же порядок байтов, что и записывающее устройство, или все байты должны быть поменяны местами.
При сохранении файла UTF-8нет никакой двусмысленности в порядке следования байтов.Но некоторые программы, особенно написанные для Windows, все еще добавляют спецификацию, закодированную как UTF-8.Когда вы кодируете кодовую точку спецификации как UTF-8, вы получите три байта: 0xEF 0xBB 0xBF.Эти байты соответствуют символам рисования прямоугольников в большинстве кодовых страниц OEM (это значение по умолчанию для окна консоли в Windows).
Аргумент в пользу этого состоит в том, что он помечает файлы как действительно UTF-8, в отличие от какой-то другой родной кодировки.Например, многие текстовые файлы в западной части Windows находятся на кодовой странице 1252. Пометка файла с помощью кодировки UTF-8 упрощает различие.
Аргумент против этого заключается в том, что большое количество программожидайте ASCII или UTF-8 независимо и не знаете, как обрабатывать дополнительные три байта.
Если бы я писал программу, которая читает UTF-8, я бы проверял точно эти три байта в начале,Если они есть, пропустите их.
Обновление: Вы можете преобразовать U+FEFF ZERO WIDTH NO BREAK
символов в U+2060 WORD JOINER
за исключением начала файла [Gillam, Richard, Unicode Demysified , Addison-Wesley, 2003, p.108].Мой личный код делает это.Если при декодировании UTF-8 я вижу 0xEF 0xBB 0xBF в начале файла, я воспринимаю это как счастливый признак того, что у меня действительно есть UTF-8.Если файл не начинается с этих байтов, я просто продолжаю декодирование в обычном режиме.Если при декодировании позже в файле я сталкиваюсь с U + FEFF, я испускаю U + 2060 и продолжаю.Это означает, что U + FEFF используется только как спецификация, а не как ее устаревшее значение.