Почему Windows 7 работает с Unicode, а не с UTF-8?
терминология
Unicode и UTF-8 - это не одно и то же: Unicode - это набор символов, который определяет набор символов (репертуар) и присваивает номера (кодовые точки) каждому из этих символов. UTF ‑ 8 является одним из нескольких кодировок, которые можно использовать для представления потока символов Unicode на диске или при передаче. Тот же поток символов Unicode также может быть закодирован, например, как UTF ‑ 16, UTF ‑ 32 или UTF ‑ 7.
Тем не менее, Notepad предлагает вам «кодирующие» варианту , включая ANSI
, Unicode
, Unicode big-endian
и UTF-8
. Разработчики Microsoft, написавшие это, использовали неправильные термины. Когда они говорят «Unicode», они, скорее всего, означают « UTF-16
little-endian ». Когда они говорят «ANSI», они имеют в виду кодовую страницу 1252 (CP-1252).
Блокнот Microsoft
Я полагаю, что Блокнот Microsoft пишет UTF-16 с меткой порядка байтов ( BOM ) и что Блокнот ищет спецификацию при чтении текстового файла. Спецификация сообщает приложению, что файл имеет формат UTF-16, и указывает, является ли он прямым или младшим.
Если Блокнот не находит спецификацию, он вызывает библиотечную функцию IsTextUnicode
, которая просматривает данные и пытается угадать, какая кодировка использовалась. Иногда (неизбежно) он угадывает неправильно. Иногда он догадывается, что файл «ANSI» - это «Unicode». Попытка интерпретировать файл UTF-16 или UTF-8 как кодовую страницу 1252 приведет к тому, что он отобразит неправильные глифы и не сможет найти глифы для отображения некоторых 8-битных значений - тогда они будут отображаться в виде квадратов.
Как Harrymc говорит в своем ответе , есть лучшие альтернативы Notepad. Но Блокнот позволяет явно выбирать кодировку при открытии файла (вместо того, чтобы пытаться угадать Блокнот).
Метки байтов
Согласно консорциуму Unicode, метки байтов (BOM) являются необязательными. Однако Windows полагается на спецификации, чтобы различать некоторые кодировки.
Короче говоря, может быть, вашим файлам по какой-то причине не хватало спецификации? Может быть, спецификация была потеряна в процессе обновления?
Если у вас все еще есть исходные файлы, которые отображаются в виде квадратов, вы можете сделать из них шестнадцатеричный дамп, чтобы увидеть, содержат ли они спецификацию.
Стандарты простого текстового файла
Проблема заключается в том, что фактически не существует никаких универсальных стандартов для простых текстовых файлов. Вместо этого у нас есть ряд несовместимых и неизвестных.
Как обозначены окончания строк? Некоторые платформы используют символы возврата каретки (CR), за которыми следует перевод строки (LF), некоторые используют только CR, а некоторые используют только LF.
Вышеуказанные терминаторы или разделители? Это влияет на конец файла и, как известно, вызывает проблемы.
Обработка вкладок и других управляющих символов. Можно предположить, что вкладка используется для выравнивания по кратности 8 стандартным символам ширины от начала строки, но на самом деле в этом нет уверенности. Многие программы позволяют изменять положение вкладок.
Набор символов и кодировка? Не существует универсального стандарта для указания того, какие из них были использованы для текста в файле. Ближайшее, что у нас есть, - это поиск наличия спецификации, которая указывает на то, что кодировка является одной из тех, которые используются для Unicode. По значению спецификации программа, читающая файл, может различать UTF-8 и UTF-16 и т. Д., А также между вариантами UTF-16 с младшим и старшим байтами и т. Д. Универсального стандарта для указания того, что файл кодируется в любой другой популярной кодировке, такой как CP-1252 или KOI-8.
И так далее. Ни один из вышеуказанных метаданных не записывается в текстовый файл, поэтому конечный пользователь должен сообщить программе при чтении файла. Конечный пользователь должен знать значения метаданных для любого конкретного файла или рисковать тем, что его программа будет использовать неправильные значения метаданных.
Буш скрыл факты
Попробуйте это на Windows XP.
- Откройте Блокнот.
- Установите шрифт Arial Unicode MS. (Возможно, вам придется сначала установить его; если вы не видите его в меню, нажмите «Показать больше шрифтов».)
- Введите текст "Буш спрятал факты".
- Выберите
Save As
. В Encoding
меню выберите ANSI
.
- Закройте Блокнот.
- Снова откройте документ (например, используя
Start
, My Recent Documents
).
- Вы увидите 畂 桳 栠 摩 琠 敨 映 捡 獴 вместо «Буш скрыл факты».
Это показывает, что IsTextUnicode
функция, используемая Блокнотом, неправильно предполагает, что текст ANSI (на самом деле Кодовая страница 1252) - это Unicode UTF-16LE без спецификации. В файле, сохраненном как, нет спецификации ANSI
.
Windows 7
С Windows 7 Microsoft отрегулирована IsTextUnicode
так, чтобы вышеуказанного не произошло. В отсутствие спецификации теперь более вероятно угадать ANSI (CP 1252), чем Unicode (UTF-16LE). Я полагаю, что с Windows-7 у вас, скорее всего, возникнет обратная проблема: файл, содержащий символы Unicode с кодовыми точками больше 255, но без спецификации, теперь с большей вероятностью будет угадан как ANSI - и, следовательно, отображается неправильно.
Предотвращение проблем с кодировкой
В настоящее время лучшим подходом является использование UTF-8 везде. В идеале вы должны перекодировать все старые текстовые файлы в UTF-8 и только когда-либо сохранять текстовые файлы как UTF-8. Есть инструменты, такие как перекодирование и iconv, которые могут помочь с этим.