Unicode w Javie i nie tylko

0

Zacząłem trochę uczyć się Javy z książki http://helion.pl/ksiazki/java_podstawy_wydanie_viii_cay_s_horstmann_gary_cornell,javpd3.htm, nie bardzo też podobał mi się użyty termin inicjacja zmiennej, zamiast inicjalizacja zmiennej, ale to nie o moje gusta teraz chodzi.

Z tego co wyczytałem, to w Javie łańcuchy tekstowe czyli po prostu Stringi to w uproszczeniu ciągi wartości typu char. Char (odpowiednik obiektowy Character), to typ 16 bitowy i każdy osobny znak (a precyzyjniej każda jednostka kodowa UTF-16), zajmuje 16 bitów.

Czy nie lepiej (oszczędniej) byłoby znaki kodować jednak w UTF-8 zamiast UTF-16, przecież tam jeden znak z ASCII, to tylko 8 bitów (tak prawdę pisząc to 7) ? Albo chociaż dać programistom wybór.

W Javie wprawdzie nie ma przedrostka unsigned dla typów, ale czy można traktować typ char jako ekwiwalent do unsigned short ? Sprawdziłem i zmiennej typu char można podawać wartości liczbowe od 0 do 65535.

Próbowałem w Eclipsie wyświetlić znaki UTF-16 występujące jako pary surogatów, czyli te, które nie należą do przestrzeni BMP np. symbole muzyczne http://unicode.org/charts/PDF/U1D100.pdf, ale konsola uporczywie zwraca znak "kwadracik", o ile dobrze rozumiem, jest to wina czcionek, że nie mają tych znaków. Jak sprawdziłem na tabelce ze strony http://en.wikipedia.org/wiki/Unicode_typeface#10000-1D7FF wszystkie czcionki mają w zakresie współrzędnych kodowych 1D100–1D1FF brak obsługi, więc nic dziwnego, że Eclipse wymiękło. Trochę to coś nie tak, z jednej strony mamy standard Unicode, z drugiej braki w czcionkach. Żeby jeszcze tylko z SMP (pary surogatów UTF-16) brakowało, a tu widze, że nawet w ramach BMP są solidne braki :/

Będę wdzięczny za wszelkie merytoryczne komentarze :)

0

UTF16 tu chyba chodzi o kilka języków większy zakres większe możliwości :) zresztą w dzisiejszych czasach kto tam się przejmuje takimi drobiazgami no chyba ze chodzi może o programowanie pralki gdzie kilobajty się liczą? ;)

0

Dlaczego nie UTF-8? Ponieważ w kodowaniu tym jeden znak może mieć od 1 do 4 bajtów. Czyli krótko mówiąc aby dostac się do n-tego znaku nie możesz użyć najprostszego i najszybszego indeksowania, lecz musisz niesamowicie wolno (w porównaniu z indeksowaniem) parsować tekst sekwencyjnie.
Kiedy Java powstawała wydawało się, że wszystkie znaki uda się zmieścić w 65536 kodach. Stąd naturalne było użycie UTF-16, zamiast kodowania jednobajtowego jak w C, nie tracąc jednocześnie zalety stałej wielkości jednostki tekstu. Gdyby Java powstała dzisiaj, to prawdopodobnie użyto by UTF-32, które obejmuje już wszystkie możliwe znaki jakie mogły się ludziom przyśnić. Z drugiej strony im więcej bajtów na znak tym więcej pamięci się marnuje - w szczególności pamięci, która w komputerze jest zawsze deficytowa (czyli RAM). UTF-16 jest więc dobrym kompromisem.

ps. A co "inicjalizacji", to jest to współczesna, prymitywna kalka językowa z angielskiego podczas gdy w j.polskim od kilku wieków jest znacznie starsze słowo z łaciny, które oznacza dokładnie to samo, jest krótsze i nie łamie języka. No, ale "polscy informatycy" oczytani raczej nie byli, stąd takie ubogie słownictwo i sprośne kaleczenie własnego języka. ;-)

0

Dzięki za wyjaśnienie, tak właśnie coś mi się zdawało, że sytuacja, w której znaki są kodowane jako 1, 2, 3 albo 4 bajty (czyli UTF-8) może być mało efektywna obliczeniowe.

Co do zdania, że UTF-16 o kilka języków większy zakres możliwości, to nie bardzo tak jest. Unicode jest cały czas jeden i ten sam, znaki nigdzie nie uciekają. UTF-8, UTF-16 i UTF-32 to tylko sposoby zapisu współrzędnych kodowych w formie ciągu bitów.

0
mfi napisał(a)

Próbowałem w Eclipsie wyświetlić znaki UTF-16 występujące jako pary surogatów, czyli te, które nie należą do przestrzeni BMP np. symbole muzyczne http://unicode.org/charts/PDF/U1D100.pdf, ale konsola uporczywie zwraca znak "kwadracik", o ile dobrze rozumiem, jest to wina czcionek, że nie mają tych znaków. Jak sprawdziłem na tabelce ze strony http://en.wikipedia.org/wiki/Unicode_typeface#10000-1D7FF wszystkie czcionki mają w zakresie współrzędnych kodowych 1D100–1D1FF brak obsługi, więc nic dziwnego, że Eclipse wymiękło. Trochę to coś nie tak, z jednej strony mamy standard Unicode, z drugiej braki w czcionkach. Żeby jeszcze tylko z SMP (pary surogatów UTF-16) brakowało, a tu widze, że nawet w ramach BMP są solidne braki :/

Będę wdzięczny za wszelkie merytoryczne komentarze :)

Kliknij prawym na projekt -> Properties -> Resource -> Text file encoding ustaw na UTF-16
Tylko przed tym skopiuj sobie cały kod i po zmianie wklej na nowo, bo prawdopodobnie zostanie zmieniony na dziwne chińskie znaczki po zmianie kodowania :)
U mnie to zadziałało i wyświetla mi różne dziwne znaczki składające się z par surogatów

Pozdrawiam

0
mfi napisał(a)

Co do zdania, że UTF-16 o kilka języków większy zakres możliwości, to nie bardzo tak jest. Unicode jest cały czas jeden i ten sam, znaki nigdzie nie uciekają.

Kiedy powstawała Java, to Unicode był kodowany tylko na 16-bitach. Nie było jeszcze UTF-8, ani kolejnej wersji rozwojowej do której dopchano kolejne znaki czyli UTF-32. Przynajmniej tak to pamiętam. Po prostu kiedyś dolna połówka UTF-16 (czyli UCS-2) i Unicode, to były synonimy. Prawie co roku od 20 lat wychodziła kolejna wersja Unikodu i kilka podwersji, więc nie można powiedzieć, że Unicode jest cały czas jeden i taki sam.

0

Racja, napisałem coś innego niż miałem na myśli. Chodziło mi, że różne kodowania UTF odwołują obecnie się do tego samego zestawu współrzędnych, nie ma tak, że np. UTF-16 potrafi zakodować więcej znaków, niż UTF-8.

Na stronie http://en.wikipedia.org/wiki/Unicode#Standard jest tabela pokazująca rozwój tego standardu, w planie jest też Unicode 6.0.

0
Odpowiadający napisał(a)
mfi napisał(a)

Próbowałem w Eclipsie wyświetlić znaki UTF-16 występujące jako pary surogatów, czyli te, które nie należą do przestrzeni BMP np. symbole muzyczne http://unicode.org/charts/PDF/U1D100.pdf, ale konsola uporczywie zwraca znak "kwadracik", o ile dobrze rozumiem, jest to wina czcionek, że nie mają tych znaków. Jak sprawdziłem na tabelce ze strony http://en.wikipedia.org/wiki/Unicode_typeface#10000-1D7FF wszystkie czcionki mają w zakresie współrzędnych kodowych 1D100–1D1FF brak obsługi, więc nic dziwnego, że Eclipse wymiękło. Trochę to coś nie tak, z jednej strony mamy standard Unicode, z drugiej braki w czcionkach. Żeby jeszcze tylko z SMP (pary surogatów UTF-16) brakowało, a tu widze, że nawet w ramach BMP są solidne braki :/

Będę wdzięczny za wszelkie merytoryczne komentarze :)

Kliknij prawym na projekt -> Properties -> Resource -> Text file encoding ustaw na UTF-16
Tylko przed tym skopiuj sobie cały kod i po zmianie wklej na nowo, bo prawdopodobnie zostanie zmieniony na dziwne chińskie znaczki po zmianie kodowania :)
U mnie to zadziałało i wyświetla mi różne dziwne znaczki składające się z par surogatów

Pozdrawiam

Próbowałem takich ustawień i ciągle dostawałem "kwadracik" zamiast oczekiwanego znaku (U+1D11E). Kod:

System.out.println("\uD834\uDD1E");

Doszedłem do wniosku, że nie jest to wina ustawień kodowania w Eclipse'ie (choć poprawne ustawienie jak najbardziej też jest istotne), a braku tego znaku w czcionce konsoli. Łatwo sprawdzić jaka to czcionka:

Window->Preferences->General->Apperance->Colors and Fonts->Debug->Console Font

Domyślnie jest ustawiona (Windows) czcionka Courier New, która nie ma takiego znaku muzycznego. Ale poszedłem dalej, ściągnąłem dodatkową czcionkę z http://openfontlibrary.org/media/files/Eimai/191. W rozpakowanym archiwum jest plik z czcionką Euterpe.ttf, który skopiowałem do C:\Windows\Fonts, potem zmieniłem czcionkę konsolową Eclipse'a na Euterpe i teraz działa :)

Edit:
Text file encoding nie musi być ustawiony na UTF-16, może być także UTF-8, to nie ma to większego znaczenia, bo to tylko sposoby zapisu kodu źródłowego w formie bajtów, Java i tak przechowuje łańcuchy w UTF-16. W moim przypadku (Windows) zarówno kodowanie kodu źródłowego, jak i konsoli było w CP1250, był nawet zgłaszany bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=108668), że domyślnie powinno być UTF-8. Zmieniłem na UTF-8 tzn.:

Window->Preferences->General->Workspace->w panelu Text file encoding->other->UTF-8
Project->Properties->Resouece->w panelu Text file encoding->Inherited from container (UTF-8)
Run-Run Configurations...->karta Common->w panelu Console Encoding->Default - inherited (UTF-8)

W takiej konfiguracji (UTF-8 na kod źródłowy i konsolę Eclipse'a) wszystkie znaki Unicode (o ile pozwala na to czcionka konsoli) będą się wyświetlać, to jest co pisałem wcześniej, że UTF-8, UTF-16, to tylko metody kodowania, a Unicode jest jeden i ten sam dla wszystkich metod kodowania UTF.

PS Może być też tak, że kod źródłowy jest w UTF-8, a konsola w UTF-16, albo na odwrót, może być UTF-16 na obydwa i też jest ok.

0
Odpowiadający napisał(a)

Kliknij prawym na projekt -> Properties -> Resource -> Text file encoding ustaw na UTF-16
Tylko przed tym skopiuj sobie cały kod i po zmianie wklej na nowo, bo prawdopodobnie zostanie zmieniony na dziwne chińskie znaczki po zmianie kodowania :)
U mnie to zadziałało i wyświetla mi różne dziwne znaczki składające się z par surogatów

Pozdrawiam

Wie ktoś może jak zmienić kodowanie w eclipse bez potrzeby kopiowania kodu (mam dobre ponad 300 klas i ręczne kopiowanie kodu po prostu mija się z celem)?

Z góry dziękuję za odpowiedz!

0

Masz kilkaset różnych i darmowych programów, które potrafią to zrobić z automatu. Po prostu potraktuj pliki źródłowe tak samo jak pliki tekstowe. W ostateczności możesz dopisać klasę, która zrobi Ci to samo. Pewnie bez większego problemu jesteś sobie w stanie taką napisać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1