Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Špatné zobrazení txt po uložení z Javy

Aktivity
Avatar
Nallim
Člen
Avatar
Nallim:26.8.2015 19:11

Ahoj,
potřeboval bych opět poradit.

Ale nejspíše to nebude problém přímo Javy, ale poznámkového bloku - kde je problém s odřádkováním.

Z Javy ukládám do txt pomocí třídy BufferedWriter.

V kódu mám použité na odřádkování "\n".

Výstup viz obrázek.

Když txt otevřu v poznámkovém bloku, zobrazí výstup bez odřádkování.
Když na zobrazení výstupu file lister, který je v Total Commanderu (F3), tak se zobrazují výstup správně - PSPad se chová stejně.

Takže v kódu nejspíše chyba nebude.

Potřeboval bych vyřešit, aby se mi to zobrazovalo správně i v poznámkovém bloku.

Uživatel výstup bude nejspíše otevírat vždy jen v poznámkovém bloku a ne třeba v PSPadu :-/

Mám špatné tušení, že to bude nevyřešitelný problém, protože se nejspíše jedná o formátování přímo poznámkového bloku. Maximálně mě napadá, že poznámkový blok nedokáže přelouskat "\n", ale zkoušel jsem i metodu přímo třídy BufferedWriter, a to také nepomohlo.

BufferedWriter newLine();

Díky za reakce.

 
Odpovědět
26.8.2015 19:11
Avatar
Nallim
Člen
Avatar
Nallim:26.8.2015 19:20

Tak prozatímní řešení mě napadlo to ukládat do csv, kde se to zobrazuje správně. Jen tedy mám problém s češtinou.

 
Nahoru Odpovědět
26.8.2015 19:20
Avatar
dobrakmato
Člen
Avatar
Odpovídá na Nallim
dobrakmato:26.8.2015 20:39

Skratene, ukoncuj riadok s \r\n.

Este lepsie je ked ho budes ukoncovat tym, co ti vrati

System.getProperty("line.separator");

popripade v Jave 7+

System.lineSeparator()

Problem je v tom, ze kazdy OS a kazda app pouziva iny new line / endline znak. Ked sa pozries na status bar PSPadu, pise tam UNIX, pravdepodobne to znamena, ze tvoj subor pouziva unixovy endline character.

Tu sa o tom dozvies viac: https://en.wikipedia.org/wiki/Newline

Editováno 26.8.2015 20:39
 
Nahoru Odpovědět
26.8.2015 20:39
Avatar
vita
Tvůrce
Avatar
Odpovídá na Nallim
vita:26.8.2015 20:43

Ahoj,
zkus sem vložit kód ať se na to můžeme podívat.

 
Nahoru Odpovědět
26.8.2015 20:43
Avatar
Nallim
Člen
Avatar
Odpovídá na dobrakmato
Nallim:26.8.2015 22:24

Díky.

S \r\n odřádkování funguje - co je to \r?

Zkusil jsem i lineSeparator (obě varianty) a ani jedna nefunguje.

 
Nahoru Odpovědět
26.8.2015 22:24
Avatar
Nallim
Člen
Avatar
Odpovídá na vita
Nallim:26.8.2015 22:25

Přikládám kód. Nechal jsem to na csv. Vyzkoušel jsem \r na txt a to funguje, jak píšu viz předchozí příspěvek.

Writer writer = null;
new File("./vysledky/" + netID).mkdirs();
File file = new File("./vysledky/" + netID + "/BP_mereni_" + netID + "_" + getDatum("Databáze") + ".csv");

writer = new BufferedWriter(new FileWriter(file));
writer.write("Pokus;Meta;Čas\n");
for (int i = 0; i < poleCasu.length; i++) {
        writer.write((i + 1) + ".;" + String.valueOf(poleMet[i]) + ".;" + String.valueOf(poleCasu[i]) + "\n");
}
writer.close();
Editováno 26.8.2015 22:26
 
Nahoru Odpovědět
26.8.2015 22:25
Avatar
dobrakmato
Člen
Avatar
Odpovídá na Nallim
dobrakmato:26.8.2015 22:30

\r alebo aj carriage return je kontrolny znak, ktory sposobi, ze sa kurzor posunie na zaciatok riadku.

Napriklad si mozes predstavit pisaci stroj. \n posunie papier o riadok dalej a \r posunie valec tak, aby si pisal na zaciatok noveho riadku.

Kazda platforma ma iny sposob ukoncenia riadku.

Vynatok z wiki:

LF: Multics, Unix and Unix-like systems (Linux, OS X, FreeBSD, AIX, Xenix, etc.), BeOS, Amiga, RISC OS and others.[1]
CR: Commodore 8-bit machines, Acorn BBC, ZX Spectrum, TRS-80, Apple II family, Mac OS up to version 9 and OS-9
RS: QNX pre-POSIX implementation.
0x9B: Atari 8-bit machines using ATASCII variant of ASCII. (155 in decimal)
LF+CR: Acorn BBC and RISC OS spooled text output.
CR+LF: Microsoft Windows, DEC TOPS-10, RT-11 and most other early non-Unix and non-IBM OSes, CP/M, MP/M, DOS (MS-DOS, PC DOS, etc.), Atari TOS, OS/2, Symbian OS, Palm OS, Amstrad CPC

Potom je nieco naozaj rozbite, netusim co. :D Nespustas to nahodou pod monom? Alebo take nieco?

 
Nahoru Odpovědět
26.8.2015 22:30
Avatar
Nallim
Člen
Avatar
Odpovídá na dobrakmato
Nallim:26.8.2015 22:31

Díky.

Nerozumím jestli to nespouštím pod "monom"? Nevím co si pod tím mám představit :)

 
Nahoru Odpovědět
26.8.2015 22:31
Avatar
dobrakmato
Člen
Avatar
Odpovídá na Nallim
dobrakmato:26.8.2015 23:11

Oh sorry, neviem preco som bol v tom, ze to je .NET a nie Java. Potom nic. Kazdopadne to vyzera ako vec, ktora sa len tak lahko vyriesit neda (http://stackoverflow.com/…19883/721809).

Jednoducho asi pouzi ten \r\n ked to tak potrebujes a je to ok.

Editováno 26.8.2015 23:11
 
Nahoru Odpovědět
26.8.2015 23:11
Avatar
vita
Tvůrce
Avatar
Odpovídá na Nallim
vita:27.8.2015 9:18

Ahoj, přikládám řešení, které se správně zobrazuje jak ve Windows notepadu, PSPadu, tak v Total Commanderu (F3):

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class FileApp {

        private static File file = new File("D:/Temp/file.txt");
        private static String text = "Line number ";

        public static void main(String[] args) {
                try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"))) {
                        for (int i = 1; i <= 10; i++) {
                                bw.write(text + i);
                                bw.newLine();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

Vysvětlení:

Kód v části try (...) se dá rozepsat následujícím způsobem:

FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
  • Vytvoří se file output stream.
  • Output stream bude používat kódování UTF-8.
  • Zápis bude použivat buffer
try (BufferedWriter bw = new ...) {
} catch (Exception e) {}

Tento způsob zápisu try se nazývá "try catch with resources" a je výhodný proto, že se postará o korektní uzavření streamu.

bw.write(text + i);
bw.newLine();

Zapíše text a následně zapíše oddělovař řádků. Jak uvedl dobrakmato, line.separator nemusí být jen znak '\n'.

Doufám, že ti to pomůže, a že ti to nyní již bude fungovat správně.

 
Nahoru Odpovědět
27.8.2015 9:18
Avatar
Nallim
Člen
Avatar
Odpovídá na vita
Nallim:27.8.2015 16:37

Skvělé, funguje.
Díky moc i za vysvětlení :-)

Jen teda stále v csv nefunguje čeština, "UTF-8" nepomohlo.

new File("./vysledky/" + netID).mkdirs();
File file = new File("./vysledky/" + netID + "/BP_mereni_" + netID + "_" + getDatum("Databáze") + ".csv");

try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"))) {
        bw.write("Pokus;Meta;Čas");
        bw.newLine();
        for (int i = 0; i <= (poleCasu.length-1); i++) {
                bw.write((i + 1) + ".;" + String.valueOf(poleMet[i]) + ".;" + String.valueOf(poleCasu[i]));
                bw.newLine();
         }
} catch (IOException e) {
        e.printStackTrace();
}
 
Nahoru Odpovědět
27.8.2015 16:37
Avatar
vita
Tvůrce
Avatar
vita:27.8.2015 16:53

A v jakém programu to otevíráš. Pokud vytvořený soubor (viz níže - file.csv) otevřu v Notepadu, PSPadu nebo Total Commanderu, tak je vše v pořádku. Problém má při otevření Excel.

public class FileApp {

        private static File file = new File("D:/Temp/file.csv");
        private static String text = "ĚŠČŘŽÝÁÍÉŮÚěščřžýáíéúů ";

        public static void main(String[] args) {
                try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"))) {
                        for (int i = 1; i <= 10; i++) {
                                bw.write(text + ";" + text + i);
                                bw.newLine();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

A co hlavička bw.write("Pokus;Me­ta;Čas")? Ta je také chybně? Pokud by byla tato hlavička správně, pak bych chybu hledal v datech, která ukládáš.
Vita

 
Nahoru Odpovědět
27.8.2015 16:53
Avatar
Nallim
Člen
Avatar
Nallim:27.8.2015 17:08

Právě že špatná čeština je jen v excelu -> poté i když parsuji csv soubor v Javě.

Právě že v té hlavičce -> Čas.

 
Nahoru Odpovědět
27.8.2015 17:08
Avatar
vita
Tvůrce
Avatar
Odpovídá na Nallim
vita:28.8.2015 8:24

I přesto, že ostatní programy s tím nemají problém, některý software společnosti Microsoft jako např. Notepad či Excel, není schopen korektně přečíst (dekódovat) soubory v UTF-8, pokud neobsahují BOM.

BOM (Byte order mark, česky přibližně „označení pořadí bajtů“) je znak hexadecimálně zapsaný jako FEFF (v desítkové soustavě 65279). wikipedie

Řešení:

public class FileApp {

        private static File file = new File("D:/Temp/file.csv");
        private static String text = "ĚŠČŘŽÝÁÍÉŮÚěščřžýáíéúů ";

        public static void main(String[] args) {
                boolean fileExists = file.exists();
                try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"))) {
                        if (!fileExists) {
                                bw.write("\uFEFF");
                        }
                        for (int i = 1; i <= 10; i++) {
                                bw.write(text + ";" + text + i);
                                bw.newLine();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

Vysvětlení:

boolean fileExists = file.exists();

Proměnná fileExists obsahuje true, v případě, že daný soubor již existuje a false v případě, že ne.

if (!fileExists) {
        bw.write("\uFEFF");
}

V případě, že soubor neexistuje (a program jej vytvoří), na začátek souboru je zapsána sekvence BOM (v Unicode FEFF). Díky tomu i Excel pozná, že se jedná o soubor v UTF.

Zdroje:

Pokud ti to nyní již bude fungovat tak jak si představuješ, akceptuj některou odpověď, aby se toto vlákno (téma) označilo jako vyřešené.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
28.8.2015 8:24
Avatar
Nallim
Člen
Avatar
Odpovídá na vita
Nallim:28.8.2015 14:04

Tak toto už funguje bez chyby. Díky moc :-)

 
Nahoru Odpovědět
28.8.2015 14:04
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 15 zpráv z 15.