2009-03-23 8 views
16

Mój przewodnik do nauki (dla egzaminu 70-536) mówi to dwa razy w rozdziale tekstu i kodowania, który jest tuż po rozdziale IO.Co oznacza "platforma .NET domyślnie używa standardu kodowania UTF-16"?

Wszystkie dotychczasowe przykłady dotyczą zwykłego dostępu do plików przy użyciu FileStream i StreamWriter.

Na stronie jest napisane: "Jeśli nie wiesz, jakie kodowanie użyć podczas tworzenia pliku, nie podawaj go, a .NET użyje UTF16" i "Podaj różne kodowania za pomocą przeciążenia konstruktora strumienia".

Nieważne, że rzeczywiste przeciążenia są na klasie StreamWriter, ale hej, cokolwiek.

Obecnie patrzę na StreamWriter w odbłyśniku i jestem pewien, że widzę, że domyślnie jest to UTF8NoBOM.

Ale nic z tego nie jest wymienione w erracie. To stara książka (oszukany błąd w obu wydaniach), więc jeśli byłaby zła, pomyślałabym, że ktoś ją odebrał ...

Sprawia, że ​​myślę, że może tego nie rozumiem.

Więc ..... wszelkie pomysły o czym mówią? Jakieś inne miejsce, w którym jest domyślne?

Po prostu jestem całkowicie zdezorientowany.

Odpowiedz

35

„UTF-16” jest uciążliwe określenie, jak to ma dwa znaczenia, które są łatwo pomylić.

Pierwsze znaczenie to seria 16-bitowych punktów kodowych. Większość z nich odpowiada bezpośrednio znakowi Unicode o tej samej liczbie; znaki poza Podstawową płaszczyzną wielojęzyczną (U + 10000 wzwyż) są przechowywane jako dwa 16-bitowe punkty kodowe, każdy z Surrogates.

Wiele języków korzysta z UTF-16 w tym znaczeniu do celów pamięci wewnętrznej, w tym jako natywny typ ciągu. Jest to zwykłe źródło zwrotów takich jak ".NET (lub Java) używa kodowania UTF-16 jako domyślnego kodowania". .NET uzyskuje dostęp do elementów takiego 16-bitowego łańcucha znaków UTF-16 naraz (tj. Na poziomie implementacji, jako uint16).

Następną rzeczą do rozważenia jest kodowanie takiego ciągu znaków UTF-16 w bajtach liniowych, do przechowywania w strumieniu pliku lub sieci. Jak zwykle, gdy przechowujesz większe liczby w bajtach, istnieją dwa możliwe kodowania: little-endian lub big-endian. Możesz więc użyć "UTF-16LE", małego endianowego kodowania UTF-16 w bajtach lub "UTF-16BE", kodowania big-endian.

(częściej używane jest "UTF-16LE", aby dodać więcej zamieszania do ognia, Windows nadaje mu głęboko mylącą i niejednoznaczną nazwę kodowania "Unicode". W rzeczywistości prawie zawsze lepiej jest używać UTF-a 8 dla przechowywania plików i strumieni sieciowych niż jeden z UTF-16LE/BE.)

Ale jeśli nie wiesz, czy garść bajtów zawiera "UTF-16LE" lub "UTF-16BE", możesz użyć Trick spojrzenia na pierwszy punkt kodowy, aby go rozwiązać.Ten punkt kodowy, Byte Order Mark (BOM), jest ważny tylko wtedy, gdy czyta się go w jedną stronę, więc nie można pomylić jednego kodowania z drugim.

Podejście polegające na tym, że nie dbamy o to, jaką masz kolejność bajtów, ale używamy do jej sygnatury zestawienia, zwykle określa się pod nazwą kodowania ... "UTF-16".

Tak więc, gdy ktoś mówi "UTF-16", nie można stwierdzić, czy chodzi o sekwencję krótkich znaków kodu Unicode, czy o sekwencję bajtów w nieokreślonej kolejności, która będzie dekodowana do jednego.

(„UTF-32” ma ten sam problem).

If you don't know what encoding to use when you create a file, don't specify one and .NET will use UTF16

Jeśli to rzeczywisty cytat jest to kłamstwo. Konstruowanie StreamWriter bez argumentu kodowania is explicitly specified, aby uzyskać kodowanie UTF-8.

+1

+1 Wow, dziękuję za tę wspaniałą odpowiedź. Trawię. Gdybym mógł dwa razy głosować, to bym :). –

2

UTF16 to domyślne kodowanie, które będzie używane przez .NET do kodowania ciągów w twoim programie (np. Zmiennych łańcuchowych).

3

Sprawdź to. Napisz ciąg "abcd" do pliku. Jeśli używa formatu UTF8, plik będzie miał rozmiar 4 bajty. Pod UTF16 będzie to 8 bajtów. (Oraz może BOM)

+0

Testowałem to podczas korzystania ze Strea mWriter poprzez breakpointing i sprawdzanie kodowania StreamWriter - był to UTF8NoBOM. Ponieważ wszystkie przykłady zostały wykonane w ten sposób, a książka się nie rozwija, nie rozumiem, o co im chodzi ... –

+0

Musisz podać kodowanie, którego używa StreamWriter. –

2

Miałem ten problem ze statyczną klasą System.IO.File.

Chciałem napisać ciąg znaków zawierający plik XML w formacie UTF-16.

Najpierw użyłem

using(StreamWriter writer = File.CreateText(xmlFilePathTarget)) 
{ 
    writer.Write(xmlString); 
} 

Ale ponieważ pisał ciąg jako UTF-8, IE nie będzie go otworzyć i wyświetlany błąd:

The XML page cannot be displayed Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.


Switch from current encoding to specified encoding not supported. Error processing resource 'file:///C:/Documents and Setti...

Głównie dzięki tym artykule znaleziono rozwiązanie polegające na jawnym użyciu konstruktora StreamWriter:

StreamWriter writer = new StreamWriter(xmlFilePathTarget, false, Encoding.Unicode));