Kódování souboru v Javě

ja

Kódování souboru v Javě
« kdy: 13. 07. 2014, 20:55:11 »
Ahoj, když uložím nějaké znaky do souboru pomocí třídy FileWriter, tak by se každý znak měl uložit jako 2 bajty (kvůli Javy, která používá UTF-16), ne ? Když tedy předchozí tvrzení bude platné, tak proč mi PSPad u souboru ukazuje kódování UTF-8 ?
« Poslední změna: 13. 07. 2014, 23:12:00 od Petr Krčmář »


andy

Re:Java, kódování souboru.
« Odpověď #1 kdy: 13. 07. 2014, 20:59:24 »
Java pouziva nejake platform defaulty. getEncoding() ti co vrati? Pozeral si sa do dokumentacie?

perceptron

Re:Java, kódování souboru.
« Odpověď #2 kdy: 13. 07. 2014, 20:59:58 »
javadoc filewritera
Citace
the constructors of this class assume that the default character encoding
takze na takom windowse zapisujete v cp1250


ja

Re:Java, kódování souboru.
« Odpověď #3 kdy: 13. 07. 2014, 21:13:36 »
Java pouziva nejake platform defaulty. getEncoding() ti co vrati? Pozeral si sa do dokumentacie?

Ok, metoda mi vrátí UTF-8, zajímavé, myslel jsem si, že Java používá UTF-16 všude.
Mám ještě jednu otázku, když ukládám znaky pomocí bajtového streamu (např. FileOutputStream), jelikož se jedná o binární soubor, tak se žádné kódování textu nepoužívá, je to tak ?

ja

Re:Java, kódování souboru.
« Odpověď #4 kdy: 13. 07. 2014, 21:29:18 »
Je to tak  :)


perceptron

Re:Java, kódování souboru.
« Odpověď #5 kdy: 13. 07. 2014, 21:31:07 »
outputstream a kamarati umoznuju zapisovat bajty (alebo polia bajtov), to je o level nizsie nez nejake znaky/chary a ich kodovanie

java pouziva utf-16 len interne, pri zapise do suborov a pod sa pouziva platform encoding / default encoding, ktory zavisi na konkretnom OS/platforme: koniec koncov to dava zmysel, aby textaky na windowse boli vo windowsovskom kodovani

Krysa1

Re:Java, kódování souboru.
« Odpověď #6 kdy: 13. 07. 2014, 21:37:34 »
Záleží na tom, co do toho streamu ukládáš. Pokud zapisuješ např byte array (byte[]), tak se logicky žádné kódování nepoužívá. Naopak, pokud zapisuješ String, tak se kódování používá. Java v ramce ukládá String v UTF-16, takže dojde ke konverzi do zvoleného kódování.


Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"), "UTF-8"));
writer.write("+ěščřžýáíé");

ja

Re:Java, kódování souboru.
« Odpověď #7 kdy: 13. 07. 2014, 22:31:07 »
Takže když budu ukládat znaky, které budou dat. typu char, tak se při uložení do bajtového streamu provede konverze na výchozí kódování, v mém případě UTF-8, chápu to dobře ?

Krysa1

Re:Java, kódování souboru.
« Odpověď #8 kdy: 13. 07. 2014, 22:50:51 »
Ano, duvůd je ten, že neexistuje jednoznačný převod znaku do byte. Záleží jaké si nasadíme "brýle", neboli zvolíme kódování. Znak 'č' bude mít jinou binárni hodnotu(včetně délky) v UTF-8 a jinou v cp-1250.

Navíc nedoporučuju spoléhat na defaultní kódování systému, ale vždy si ho nastavit.

Natix

Re:Java, kódování souboru.
« Odpověď #9 kdy: 14. 07. 2014, 00:49:04 »

Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"), "UTF-8"));
writer.write("+ěščřžýáíé");


^ Toto

Re:Kódování souboru v Javě
« Odpověď #10 kdy: 14. 07. 2014, 10:29:51 »
Třídy java.io.FileReader a java.io.FileWriter by se (mimo nějakých prototypů) vůbec neměly používat, mají špatně navržené API. Používají kódování souborů, které se sebere bůhvíkde*), což je špatně – někde to pak magicky funguje (trefí se náhodou to kódování, které programátor chtěl), jinde se to pak zase magicky rozbíjí. Správně má programátor vždy znakovou sadu určit, a pokud chce použít znakovou sadu platformy, má to explicitně uvést. Takže je nutné používat kombinaci FileOutputStream+OutpuStreamWriter resp. FileInputStream+InputStreamReader.
java.io.OutputStreamWriter a java.io.InputStreamReader jsou na tom sice podobně, ale mají přetížené konstruktory, kde se znaková sada uvádí, takže tam je špatně vždy jen ten jeden konstruktor.

*) Ve skutečnosti je to voláním java.nio.charset.Charset#defaultCharset, ale není to napsané ani v dokumentaci těch tříd. Metoda defaultCharset() bere kódování ze systémové vlastnosti file.encoding, a pokud není nastavena, bere se výchozí kódování platformy – na unixech podle locale, na Windows znaková sada systému.

karel

Re:Kódování souboru v Javě
« Odpověď #11 kdy: 14. 07. 2014, 19:06:31 »
tak ono by to mělo platit obecně, bez ohledu na jazyk, vždy uvádět znakovou sadu souboru, člověk se opravdu vyhne problémům  :P

Kit

Re:Kódování souboru v Javě
« Odpověď #12 kdy: 14. 07. 2014, 19:38:47 »
tak ono by to mělo platit obecně, bez ohledu na jazyk, vždy uvádět znakovou sadu souboru, člověk se opravdu vyhne problémům  :P

K čemu pak jsou proměnné prostředí?

Pokud výstup chci v nějakém kódování (např. UTF-8 pro výstup v HTML), tak ho samozřejmě uvedu, ale pokud má jít výstup na terminál, tak by aplikace měla respektovat nastavení prostředí.

Re:Kódování souboru v Javě
« Odpověď #13 kdy: 14. 07. 2014, 19:50:51 »
tak ono by to mělo platit obecně, bez ohledu na jazyk, vždy uvádět znakovou sadu souboru, člověk se opravdu vyhne problémům  :P
Je dost smutné, že při komunikace přes internet se znaková sada a mime typ běžně uvádí (v HTTP hlavičkách, v hlavičkách e-mailu), ale na disku se to do metadat souborů neukládá, a každá aplikace to musí znovu a znovu hádat (přitom běžné souborové systémy metadata souborů podporují už dost dlouho). Pak existují taková zvěrstva jako v HTML a XML, kde se kódování textu souboru dozvíte někde veprostřed textu toho souboru. Zajímalo by mne, jak vypadá oficiální algoritmus pro detekci kódování těchto souborů.

Kit

Re:Kódování souboru v Javě
« Odpověď #14 kdy: 14. 07. 2014, 20:06:16 »
tak ono by to mělo platit obecně, bez ohledu na jazyk, vždy uvádět znakovou sadu souboru, člověk se opravdu vyhne problémům  :P
Pak existují taková zvěrstva jako v HTML a XML, kde se kódování textu souboru dozvíte někde veprostřed textu toho souboru. Zajímalo by mne, jak vypadá oficiální algoritmus pro detekci kódování těchto souborů.

V XML je kódování uvedeno na prvním řádku. Pokud tam není, procesor se pokusí uhodnout, zda je tam UTF-8, UTF-16 nebo UTF-32. To jde poměrně snadno. Jiná kódování se nezkouší.