Csalódtam a rendszeremben. Pár nappal ezelöttig abban a szent meggyőződésben voltam, hogy a Kubuntu tetőtől talpig UTF-8 kódolással dolgozik. Nos ez többnyire igaz. A java VM esetén az stdout alapértelmezett kódolása latin-1, ami normális esetben nem tűnik fel. Önálló labor feladatom során merült fel, hogy egy java program kimenetét kellett böngészőben megjeleníteni. A program bemenetként egy UTF-8 kódolású XML fájlt kapott, fel sem merült bennem, hogy gond lehet a kódolással.
Meglepetésemre a program kimenetén minden ékezetes karaktert szorgalmasan kicserélt egy-egy kérdőjelre. Néhány óra bogarászás és kutatás után kiderült, hogy a Java belső kódolásként [[http://hu.wikipedia.org/wiki/UCS|UCS]]-t használ, minden bemenetet erre konvertál, és ebből alakítja át a kimenetet a megfelelő kódolásra.
További kutatással sikerült egy egyszerű módot találnom, amivel beállíthatom a sztandard kimenet kódolását. UTF-8 beállításához a következő néhány sorral kell kezdeni a main()
függvényt:
try{
PrintStream out = new PrintStream(System.out,true,"UTF-8");
System.setOut(out);
}catch(Exception e){}
Rövid magyarázat: a PrintStream osztály egy egyszerű szűrőként dolgozik, ami a bemenetét UTF-8-ra átkódolva adja tovább a megadott Stream-re (jelen esetben a System.out). Ezután beállítjuk a létrehozott Stream-et alapértelmezett kimenetként. Voilá. Minden további kimenet UTF-8 kódolású lesz.
Tényleg gyönyörű dolgokat lehet a karakterkódolásokkal művelni. Külön röhej, hogy az Eclipse alapértelmezetten valamilyen közép-európai kódolást ajánl fel a forrásfájloknak. Windows-on az ISO változatot, Mac-en egy Mac CE típust. Szóval tényleg el lehet szórakozni vele szépen.
Egyébként meg az oldal története során küzdöttem már párszor szintén a karakterkódolásokkal. Nem egy hálás téma, rengeteg szívás csak azért, hogy minden úgy menjen, ahogy az elvárható.
Nálam az eclipse UTF-8-at használ alapértelmezetten, azzal nem volt soha problémám. De valóban általános ez a probléma. Szvsz ebből a szempontból átmeneti állapotban van az ipar, épp kihevertük az ascii megrázkódtatásait és az alternatívák alkotta káosz között lavírozva haladunk az UTF-8 felé, ami (talán) a megváltást hozza magával.
Legkorábban akkor hoz megváltást, ha a Java-n belül is UTF-8 lesz, nem pedig a most használt UTF-16. Addig csak közelíthetjük az ideális állapotot, de el nem érhetjük. Az UTF-8 és az UTF-16 között elég alapvető különbség, hogy az UTF-16 fix szélességű (azaz minden karakter két bájt), míg az UTF-8 nem (karakterenként 1-3 byte). Szóval ebben még mindig vannak lehetőségek szívásra.
Ezekkel a dolgokkal még sok játék lesz, a legkülönfélébb nyelvek UTF-támogatása is problémás, gondolok itt az egyik legelterjedtebb webes nyelvre, a PHP-ra.
A PHP-val még mindig kevesebbet szívok, ugyanis az nemes egyszerűséggel nem törődik a kódolással, így olyan kódolású a kimenet, mint a bemenet. Ha minden UTF-8 lenne, akkor ezzel nem jelentene problémát. Csak azért hiányoznak a különböző kódolást támogató függvények, mert vannak különböző kódolások. (nem állítom, h az UTF-8-nak kell lennie a végső válasznak, de könyebb lenne az élet, ha csak egyféle kódolással kéne számolni)
Arról nem is beszélve, hogy a PropertyResourceBundle fájlokat (ami a programok honosításához legegyszerűbben használható, beépített megoldás) latin-1 (!) kódolással hajlandó csakis és kizárólag beolvasni a Java, a többi karaktert escape kóddal kell belebuherálni. És mindezt az a Java teszi, amiben a core string típus támogatja a Unicode-ot, és mindezt pont abban a feature-ben, amit a legtöbben használnának i18n-re. Hackkel meg lehet oldani, h más kódolást is elfogadjon, de akkor az automatikus locale-resourcebundle hozzárendelés nem oldható meg. Szóval no comment… 🙁
Az élet szép. Honosítani meg minek? Használjon mindenki kínait 🙂 Na jó, lehet tört angol is 🙂