Чому 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 ) і що Блокнот шукає BOM під час читання текстового файлу. BOM повідомляє програмі, що файл UTF-16, і вказує, чи є він великим або маленьким.
Якщо Блокнот не знаходить BOM, він викликає функцію бібліотеки IsTextUnicode
, яка розглядає дані та намагається відгадати, яке кодування було використано. Іноді (неминуче) він здогадується неправильно. Іноді здогадується, що файл "ANSI" - це "Unicode". Спроба інтерпретувати файл UTF-16 або UTF-8 як код сторінки 1252 призведе до того, що він відображатиме неправильні гліфи та не може знайти глифи, щоб надати деякі 8-бітні значення - вони потім відображатимуться як квадрати.
Як говорить у своїй відповіді harrymc , існують кращі альтернативи «Блокноту». Але Блокнот дозволяє явно вибрати кодування під час відкриття файлу (а не залишати Блокнот, щоб спробувати здогадатися).
Байтові позначки
За даними консорціуму Unicode, позначки байтів (BOMs) не є обов'язковими. Однак Windows покладається на BOM, щоб розрізняти деякі кодування.
Отже, коротше, можливо, вашим файлам чомусь не вистачало BOM? Можливо, BOM був загублений десь під час оновлення?
Якщо у вас все ще є оригінальні файли, які відображаються у вигляді квадратів, ви можете зробити шістнадцятковий дамп з них, щоб побачити, чи містять вони BOM.
Прості стандарти текстових файлів
Проблема полягає в тому, що їх фактично немає - немає універсальних стандартів для текстових файлів. Натомість у нас є низка несумісних та невідомих.
Як позначені закінчення рядків? Деякі платформи використовують контрольні символи Carriage Return (CR) з наступним подачею ліній (LF), деякі використовують CR окремо, а деякі використовують LF поодинці.
Чи є вищезгадані термінатори чи роздільники? Це впливає на кінець файлу, і, як відомо, воно може спричинити проблеми.
Обробка вкладок та інших контрольних символів. Можна припустити, що вкладка використовується для вирівнювання до кратної 8 стандартних ширин символів від початку рядка, але насправді в цьому немає впевненості. Багато програм дозволяють змінювати положення вкладок.
Набір символів та кодування? Не існує універсального стандарту, який би вказував, який із них використано для тексту у файлі. Найближчим із них є пошук BOM, який вказує на те, що кодування є одним із тих, що використовуються для Unicode. За значенням BOM програма, що читає файл, може відрізняти UTF-8 та UTF-16 тощо, а також між Little-Endian та Big-Endian варіантами 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 без BOM. У файлі, збереженому як, немає BOM ANSI
.
Windows 7
У Windows 7 Microsoft налаштувала IsTextUnicode
так, щоб цього не відбулося. За відсутності BOM тепер більше шансів здогадатися про ANSI (CP 1252), ніж Unicode (UTF-16LE). У Windows-7 , я очікую , що ви, таким чином , більш імовірно , буде мати зворотну задачу: Файл , що містить символи Unicode з кодами більше 255, але без BOM, тепер більш імовірно, здогадалися , як ANSI - і тому відображається неправильно.
Запобігання проблемам з кодуванням
В даний час найкращим підходом є використання UTF-8 скрізь. В ідеалі ви б перекодувати всі старі текстові файли в UTF-8 і зберегти лише текстові файли як UTF-8. Є такі інструменти, як recode та iconv, які можуть допомогти у цьому.