Portál AbcLinuxu, 1. května 2025 18:57
...tuhle blbost už řeším půl dne a nedovedu si to vysvětlit. Přitom je mi jasný, že to bude totální prkotina....můj věčný Linuxový problém
The Java programming language is based on the Unicode character set, and several libraries implement the Unicode standard. The primitive data type char in the Java programming language is an unsigned 16-bit integer that can represent a Unicode code point in the range U+0000 to U+FFFF, or the code units of UTF-16. The various types and classes in the Java platform that represent character sequences - char[], implementations of java.lang.CharSequence (such as the String class), and implementations of java.text.CharacterIterator - are UTF-16 sequences.(Zdroj.) Teď tu ale je otázka, co s tím.
OutputStreamWriter(OutputStream out, Charset cs)
CharsetEncoder
nebo (v tomhle případě dostačující) String.getBytes(String)
.
Vždycky když budes převádět znaky na byty (nebo opačně) a nebudeš mít nikde v programu exiplicitně uvedené kódování je dobré se zastavit a zjistit co bude Java dělat "by default". Většinou to asi bude používát výchozí charset (Charset.defaultCharset())
, ale i v tom případě je dobré si říct "je to to co chci?".
Vždycky když budes převádět znaky na byty (nebo opačně) a nebudeš mít nikde v programu exiplicitně uvedené kódování je dobré se zastavit a zjistit co bude Java dělat "by default". Většinou to asi bude používát výchozí charset (Charset.defaultCharset())
, ale i v tom případě je dobré si říct "je to to co chci?".
Za používání výchozího kódování platformy by měly být stanoveny tělesné tresty String.getBytes()
člověk opraví a pošle patch, ale v uzavřeném software je to lahůdka.
Mám knížku od Ivora Hortona, kde se píše, že to "je sice trošku složitější, ale výkon je vyšší" (to mluvil o bufferech).ByteBuffer (NIO) bude rychlejší v případě, že se tím odstraní nějaké zbytečné kopírování – tedy pokud kopírujete přímo ze souboru do souboru, nebo možná při kopírování ze socketu do souboru (nebo naopak). Případně tedy při kopírování mezi souborem nebo socketem a pamětí, jenže data jen tak někde v paměti vám budou celkem k ničemu, a jakmile s nimi začnete něco dělat, budou se stejně nejspíš muset někam okopírovat. V tom kódu se ale stejně nepoužívají přímé buffery (taky k čemu), takže o vyšším výkonu se dá minimálně pochybovat. Pro začínajícího programátora (v jakémkoli jazyce) bych doporučoval zapomenout na jakékoli optimalizace nebo cokoliv ve smyslu „je to sice složitější, ale…“. Je dobré se nejprve naučit, jak se ta která činnost v Javě (nebo jiném jazyce) normálně dělá. Až budete zvládat základní věci a proniknete do jazyka trochu víc, můžete se začít zabývat tím, jak JVM funguje, jak fungují různé třídy z JRE, jak rpogramovat vícevláknové aplikace atd. Pak teprve se můžete začít zabývat tím, kde je program neefektivní, a teprve když máte zjištěno, která část kódu zdržuje nejvíc, má smysl začít ten kód optimalizovat. Pokud totiž začne optimalizovat začátečník, dopadne to většinou tak, že optimalizuje část programu, která nemá žádný výkonostní problém, přepíše program tak, že je nečitelný a naseká v něm nejspíš spoustu chyb, a ve výsledku to nejspíš bude ještě pomalejší. Taky mám každou chvíli nutkání něco napsat obecněji nebo to optimalizovat pro vyšší výkon, ale vždy je potřeba si položit otázku: a je to vůbec potřeba?
Pro začínajícího programátora (v jakémkoli jazyce) bych doporučoval zapomenout na jakékoli optimalizace nebo cokoliv ve smyslu „je to sice složitější, ale…“. Je dobré se nejprve naučit, jak se ta která činnost v Javě (nebo jiném jazyce) normálně dělá. Až budete zvládat základní věci a proniknete do jazyka trochu víc, můžete se začít zabývat tím, jak JVM funguje, jak fungují různé třídy z JRE, jak rpogramovat vícevláknové aplikace atd. Pak teprve se můžete začít zabývat tím, kde je program neefektivní, a teprve když máte zjištěno, která část kódu zdržuje nejvíc, má smysl začít ten kód optimalizovat. Pokud totiž začne optimalizovat začátečník, dopadne to většinou tak, že optimalizuje část programu, která nemá žádný výkonostní problém, přepíše program tak, že je nečitelný a naseká v něm nejspíš spoustu chyb, a ve výsledku to nejspíš bude ještě pomalejší.Je to řečeno naprosto přesně. Já jsem ten kód nepoužil proto, abych optimalizoval, ale popravdě řečeno proto, že jsem byl líný se mrknout na jiný postup -- zejména ve chvíli, kdy jsem se dověděl, že "takhle to je přece lepší". Jinými slovy, udělal jsem přesně to, o čem vím, že se to nemá dělat: "takhle to zatím stačí, nevadí, že tomu nerozumím, někdy to předělám". Tímto způsobem bohužel vzniklo hodně softwaru.
To je teda masakr, proč tak složitě?Nicméně, jak bys to tedy řešil ty? Bez bufferů?
try { FileWriter writer = new FileWriter(new File("nejaka_cesta_k_uloznemu_souboru")); writer.write(outputString); writer.close(); } catch (IOException e) { e.printStackTrace(System.err); }...se tváří, jako že to dělá to, co chceš. A dokonce je to kratší (i když ne tak krátké, jako by to bylo v Ruby nebo v Lispu.
...se tváří, jako že to dělá to, co chceš.Nejenže se to tak tváří, ono to tak dokonce i funguje.
i když ne tak krátké, jako by to bylo v Ruby nebo v Lispu.
Pozor na to, že soubor bude v defaultním kódováním platformy (podle LC_CTYPE na unixech, nastavení prostředí ve windows)....se tváří, jako že to dělá to, co chceš.Nejenže se to tak tváří, ono to tak dokonce i funguje.
byte b = (byte)outputString.charAt(i);
//buffer.putChar(outputString.charAt(i));
buffer.put(b);
S pomocí komentářů uživatelů Kyosuke a Mír jsem se dopátral k tomu, že Java netiskne do souboru v UTF-8, ale UTF-16, takže se vlastně nejedná o chybu v kódu. Ještě jednou díky.Já bych to upřesnil...ty tu prostě provádíš výstup binárních hodnot znaků, tak, jak jsou v paměti - takže vlastně provádíš výstup šestnáctibitových celá čísel bez znaménka, a pro Javu je výchozí endianness Big Endian, tj. "network order".
Lepší koupit knihu nenahraditelnou než zbytečnou.Otázkou jen je, jak zjistíš, co je nenahraditelné a co zbytečné. Já to v obchodě prostě nepoznám.
Chmm. Ta kniha mě stála tisícovku a řekl bych, že je vesměs dobrá. Sice je přeložená úplně šíleně, ale tak nějak mi poskytuje to, co chci.A to je co? (co chceš) Já tu knihu neznám, ale pochopil jsem to takto: ty jsi začátečník a při pokusu o triviální zápis do souboru jsi vyrobil naprostou obludnost. To je zcela v pořádku pokud bys to vyrobil sám od sebe (zkoumáním API). Od toho jsou knihy/učebnice/tutorialy, aby tomu zabránily. Jenomže ty jsi to vyrobil právě podle učebnice, která tedy žalostně selhala. PS. V knize nazvané "Beginning Java" nemá vůbec NIO co dělat - maximálně jako zmínka že je API umožňující efektivnější práci s IO (především soubory, sockety) pro toho, kdo ví co dělá a proč.
A to je co? (co chceš)Chci nějaký základní náhled na věc a vědět, co mám dál hledat.
Já tu knihu neznám, ale pochopil jsem to takto: ty jsi začátečník a při pokusu o triviální zápis do souboru jsi vyrobil naprostou obludnost. To je zcela v pořádku pokud bys to vyrobil sám od sebe (zkoumáním API). Od toho jsou knihy/učebnice/tutorialy, aby tomu zabránily. Jenomže ty jsi to vyrobil právě podle učebnice, která tedy žalostně selhala.No, já bych to zase tak nesváděl na knihu. Ber to tak, že tohle byl první postup zápisu do souboru, který jsem našel v kapitole Zápis do souboru. Třeba byl někde i další postup.
PS. V knize nazvané "Beginning Java" nemá vůbec NIO co dělat - maximálně jako zmínka že je API umožňující efektivnější práci s IO (především soubory, sockety) pro toho, kdo ví co dělá a proč.Ta kniha Beginning Java má 1300 stránek a už na obálce se píše, že naučí naprosté základy i psaní větších aplikací. Myslím, že si zmínění java.nio může dovolit.
Jasně, knížky nejsou nejaktuálnější a není v nich všechno, takže se snažím se koukat do dokumentace atd.Proto je lepsi kupovat knihy o vecech, ktere tak rychle nezastaravaji (taky mam knihu o Pythonu 2.2.....) a rychle se menici veci studovat z internetu. Zrovna na Javu (at uz SE nebo EE) je na internetu mnoho kvalitnich materialu. Ja si dneska poridil Navrhove vzory, coz je jedna z prvnich obsahlejsich veci na toto tema v cestine a rozhodne nezastara tak rychle jako kniha o konkretnim programovacim jazyce.
Ja si dneska poridil Navrhove vzory, coz je jedna z prvnich obsahlejsich veci na toto tema v cestine a rozhodne nezastara tak rychle jako kniha o konkretnim programovacim jazyce.A můžeš o ní pár slov? Někdy
package rup.česky.vzory._04_neměnné
nebo metodou kdoVolá()
bych se asi zžít nedokázal.
#####Nadpis 1#####Nějaký text k tomu #####Nadpis 2#####A zase text k tomu #####Nadpis 3#####Úplně jiný text k tomuOno by asi bylo nejjednodušší načíst ty záznamy do pole (mám metodu pro nečtení záznamů do pole objektů), tu nepotřebnou položku z pole smazat a pak to zapsat celé znova. Nicméně mám vážné pochyby o efektivnosti.
Teoreticky ne, ale to už by znamenalo vyřešit správně zamykání, mít nějaký buffer (protože mazaný záznam může být kratší, než následující záznam, který mám na jeho místo vložit. Rozhodně bych se do takovéhle optimalizace nepouštěl hned na začátkuJá bych se do toho taky nepouštěl. Jen jsem se ptal.
Problémy se zápisem do souborů hrozí oběma řešením.V prvním případě hrozí jen to, že ten konkrétní soubor nebude zapisovatelný. V druhém navíc hrozí, že nebude zapisovatelný adresář.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.