Dlaczego system Windows 7 działa z Unicode, a nie z UTF-8?
Terminologia
Unicode i UTF-8 to nie to samo: Unicode to zestaw znaków, który definiuje zestaw znaków (repertuar) i przypisuje liczby (punkty kodowe) każdemu z tych znaków. UTF ‑ 8 jest jednym z kilku kodowań, które mogą być używane do reprezentowania strumienia znaków Unicode na dysku lub w transmisji. Ten sam strumień znaków Unicode można również zakodować na przykład jako UTF ‑ 16, UTF ‑ 32 lub UTF ‑ 7.
Jednak oferty Notatnika „kodowania” Opcje tym ANSI
, Unicode
, Unicode big-endian
i UTF-8
. Programiści Microsoft, którzy to napisali, użyli złych terminów. Kiedy mówią „Unicode”, najprawdopodobniej mają na myśli „ UTF-16
little-endian ”. Kiedy mówią „ANSI”, mają na myśli Kod Strony 1252 (CP-1252).
Microsoft Notepad
Wierzę, że Notatnik Microsoft zapisuje UTF-16 ze znakiem kolejności bajtów ( BOM ) i że Notatnik szuka BOM podczas czytania pliku tekstowego. LM informuje aplikację, że plik to UTF-16 i wskazuje, czy jest to big-endian czy little-endian.
Jeśli Notatnik nie znajdzie BOM, wywołuje funkcję biblioteki IsTextUnicode
, która sprawdza dane i próbuje zgadnąć, jakie kodowanie zostało użyte. Czasami (nieuchronnie) zgaduje niepoprawnie. Czasami zgaduje, że plik „ANSI” to „Unicode”. Próba interpretacji pliku UTF-16 lub UTF-8 jako kodu strony 1252 spowodowałaby, że wyświetlałby on niewłaściwe glify i nie byłby w stanie znaleźć glifów wyświetlających niektóre wartości 8-bitowe - byłyby wówczas pokazane jako kwadraty.
Jak mówi harrymc w swojej odpowiedzi , istnieją lepsze alternatywy dla Notatnika. Ale Notatnik pozwala jawnie wybrać kodowanie podczas otwierania pliku (zamiast pozostawiać Notatnika, aby zgadnąć).
Bajtowe znaki porządkowe
Według konsorcjum Unicode znaki bajtowe (BOM) są opcjonalne. Jednak system Windows wykorzystuje BOM do rozróżnienia niektórych kodowań.
Krótko mówiąc, może twoje pliki nie miały BOM z jakiegoś powodu? Może BOM został utracony podczas procesu aktualizacji?
Jeśli nadal masz oryginalne pliki wyświetlane jako kwadraty, możesz zrobić ich zrzut heksadecymalny, aby sprawdzić, czy zawierają one BOM.
Zwykłe standardy plików tekstowych
Problem polega na tym, że nie ma żadnego - nie ma uniwersalnych standardów dla zwykłych plików tekstowych. Zamiast tego mamy wiele niekompatybilnych i nieznanych.
Jak zostały oznaczone zakończenia linii? Niektóre platformy używają znaków kontrolnych Carriage Return (CR), a następnie Line Feed (LF), niektóre używają tylko CR, a niektóre same LF.
Czy powyższe terminatory lub separatory? Ma to wpływ na koniec pliku i wiadomo, że powoduje problemy.
Traktowanie tabulatorów i innych znaków kontrolnych. Możemy założyć, że tabulator służy do wyrównania do wielokrotności 8 standardowych szerokości znaków od początku linii, ale tak naprawdę nie ma co do tego pewności. Wiele programów pozwala na zmianę pozycji tabulatorów.
Zestaw znaków i kodowanie? Nie ma uniwersalnego standardu określającego, które z nich zostały użyte dla tekstu w pliku. Najbliższe mamy poszukać BOM, który wskazuje, że kodowanie jest jednym z tych używanych w Unicode. Od wartości BOM program odczytujący plik może odróżnić UTF-8 i UTF-16 itp., A także warianty UTF-16 Little-Endian i Big-Endian itp. Nie ma uniwersalnego standardu wskazującego, że plik jest zakodowany w dowolnym innym popularnym kodowaniu, takim jak CP-1252 lub KOI-8.
I tak dalej. Żadna z powyższych metadanych nie jest zapisana w pliku tekstowym - więc użytkownik końcowy musi poinformować program podczas czytania pliku. Użytkownik końcowy musi znać wartości metadanych dla dowolnego określonego pliku lub ryzykować, że jego program użyje niewłaściwych wartości metadanych.
Bush ukrył fakty
Wypróbuj to w systemie Windows XP.
- Otwórz Notatnik.
- Ustaw czcionkę na Arial Unicode MS. (Być może trzeba go najpierw zainstalować; jeśli nie widzisz go w menu, kliknij „Pokaż więcej czcionek”).
- Wpisz tekst „Bush ukrył fakty”.
- Wybierz
Save As
. Z Encoding
menu wybierz ANSI
.
- Zamknij Notatnik.
- Ponownie otwórz dokument (np. Za pomocą
Start
, My Recent Documents
).
- Zamiast „Bush ukrył fakty” zobaczysz 畂 桳 栠 摩 琠 敨 映 捡 獴.
To pokazuje, że IsTextUnicode
funkcja używana przez Notatnik niepoprawnie zgaduje, że tekst ANSI (naprawdę Code Page 1252) to Unicode UTF-16LE bez BOM. W pliku zapisanym jako nie ma BOM ANSI
.
System Windows 7
W systemie Windows 7 Microsoft dostosował się IsTextUnicode
tak, aby powyższe nie miało miejsca. W przypadku braku BOM, bardziej prawdopodobne jest odgadnięcie ANSI (CP 1252) niż Unicode (UTF-16LE). W systemie Windows-7 spodziewam się, że problem odwrotności jest większy : plik zawierający znaki Unicode o punktach kodowych większych niż 255, ale bez BOM, jest bardziej prawdopodobne, że zostanie odgadnięty jako ANSI - i dlatego jest wyświetlany niepoprawnie.
Zapobieganie problemom z kodowaniem
Obecnie najlepszym podejściem wydaje się być używanie UTF-8 wszędzie. Idealnie byłoby ponownie zakodować wszystkie stare pliki tekstowe do UTF-8 i zapisywać tylko pliki tekstowe jako UTF-8. Istnieją narzędzia, takie jak przekoduj i iconv, które mogą w tym pomóc.