Problem z zapisaem pliku txt - nie ma podziału na wiersze

0

Witam wszystkich jako ze jest to mój pierwszy post na tym forum. Podczas pisania prostego edytora tekstu napotkałem na problem, mianowicie przy zapisywaniu pliku tekstowego z poziomu programu (który składa się z kilku kolumn tekstu) po ponownym odczycie linie tekstu znajdują się wszystkie w jednym wierszu... tak jakby program nie zapisywał informacji o końcu wiersza, tylko ładował wszystko do jednej linijki :/ Będę bardzo wdzięczny za wskazówkę jak to poprawić.
Pozdrawiam [browar]

package io;
import javax.swing.*;
import java.io.*;
/**
 *
 * @author  student
 */
public class Okno extends javax.swing.JFrame {

    /** Creates new form Okno */
    public Okno() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("Wczytaj");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        jButton2.setText("Zapisz");
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton2MouseClicked(evt);
            }
        });

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {                                      
// TODO add your handling code here:
    JFileChooser wybierz=new JFileChooser();
    int powrot=wybierz.showOpenDialog(this);
    if(powrot==JFileChooser.APPROVE_OPTION){
        File wybrany=wybierz.getSelectedFile().getAbsoluteFile();
        int i;
        FileInputStream fin;
        try{
        fin=new FileInputStream(wybrany.getAbsolutePath());
        }
        catch(Exception e){
            System.out.println("Błąd podczas otwierania pliku");
            return;
        }
        try{
            do{
                i=fin.read();
                if(i!=-1) this.jTextArea1.setText(this.jTextArea1.getText()+(char) i);
            }while(i!=-1);
        }
        catch(Exception e){
            
        }
    }
}                                     

private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {                                      
// TODO add your handling code here:
    JFileChooser wybierz=new JFileChooser();
    int powrot=wybierz.showSaveDialog(this);
    if(powrot==JFileChooser.APPROVE_OPTION){
    try{
        FileOutputStream plik=new FileOutputStream(wybierz.getSelectedFile().getAbsolutePath());
        String a=this.jTextArea1.getText();
        for(int i=0;i<a.length();i++){
            plik.write((int) a.charAt(i));
        }
    }
    catch(Exception e){
        System.out.println("Błąd podczas zapisu");
    }
   }
}                                     

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Okno().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    // End of variables declaration                   

}
0
		File outputFile = new File("c:\\out.txt");
	                FileWriter writer= new FileWriter(outputFile);
			writer.write("This is a\n test");
	                writer.close();

Zwróć uwagę na "\n" - znak końca linii.

0

ja do zapisu i odczytu zwykłem używać BufferedWritera/Readera, przykład:

File f = new File("bla bla bla");
//writer
BufferedWriter writer = new BufferedWriter(new FileWriter(f));
writer.write("linia pierwsza");
writer.newLine();
writer.write("linia druga"); 
(...)
writer.close();

//reader
BufferedReader reader = new BufferedReader(new FileReader(f));
String liniaTekstu = reader.readLine();
String kolejnaLiniaTekstu = reader.readLine();
(...)
reader.close();
0

@Billy już napisał jak zapisywać i odczytywać pliki tekstowe.
Dopiszę swoje uwagi.

  1. U mnie (windows XP) Twój program działa dobrze. Oglądałeś utworzony przez siebie plik tekstowy w swoim programie, czy w Notatniku? Notatnik "nie wie", że bajt o kodzie ASCI 10 oznacza w niektórych SO przejście do nowego wiersza.
  2. Nigdy nie buduj Stringa w taki sposób
            do{
                i=fin.read();
                if(i!=-1) this.jTextArea1.setText(this.jTextArea1.getText()+(char) i);
            }while(i!=-1);

pętla

        String zwrot="";
        for (int i=1;i<=ile;i++)
        {
            zwrot+=s;
        }

jest (dla ile=100000, s="A") około 6000 razy wolniejsza niż pętla

        StringBuffer zwrot=new StringBuffer("");
        for (int i=1;i<=ile;i++)
        {
            zwrot.append(s);
        }
  1. Imo nie powinno się tworzyć obiektów typu JFileChooser w obsłudze zdarzenia.
private void jButton2MouseClicked(java.awt.event.MouseEvent  evt) {                                     
    JFileChooser wybierz=new JFileChooser();

Zmusza to użytkownika do wielokrotnego wędrowania po katalogach. Zauważ, że wszystkie edytory po kolejnym otwarciu okna wyboru pliku (zapis lub odczyt) pokazują katalog wybrany poprzednio. Zmienna wybierz powinna być polem w klasie, a instrukcja

    JFileChooser wybierz=new JFileChooser();

powinna wylądować w metodzie initComponents().

0

Albo mozna zapamietac ostatni katalog usera i nowe choosera inicjalizowac ta wlasnie sciezka. Ale ogolnie to masz racje ;-)

0
bo napisał(a)

pętla

        String zwrot="";
        for (int i=1;i<=ile;i++)
        {
            zwrot+=s;
        }

jest (dla ile=100000, s="A") około 6000 razy wolniejsza niż pętla

        StringBuffer zwrot=new StringBuffer("");
        for (int i=1;i<=ile;i++)
        {
            zwrot.append(s);
        }

Sprawdziłem xD. Mój kod:

double time = System.currentTimeMillis(),time2;
System.out.println("start: "+time);
String s = "A"; StringBuffer zwrot=new StringBuffer("");
for (int i=1;i<=100000;i++) {
    zwrot.append(s);
}
time2 = System.currentTimeMillis();
System.out.println("koniec: "+time2+", czas działania (ms):  "+String.valueOf(time2-time));

dał Output: (kilkukrotnie powtarzany)

start: 1.277031790421E12
koniec: 1.277031790437E12, czas działania (ms):  16.0

oraz drugi kod:

double time = System.currentTimeMillis(),time2;
System.out.println("start: "+time);
String s = "A", zwrot="";
for (int i=1;i<=100000;i++) {
    zwrot+=s;
}
time2 = System.currentTimeMillis();
System.out.println("koniec: "+time2+", czas działania (ms):  "+String.valueOf(time2-time));

który daje Output:

start: 1.277031852703E12
koniec: 1.277031889812E12, czas działania (ms):  37109.0

Czyli mniej niż 0,1 sekundy kontra ponad 37 sekund ;). W moim teście wypadło może nie ~6000 razy gorzej (bo ~2319), ale to i tak daje do myślenia :).
Dzięki 'bo' za tego msg, zawsze w sumie się nie zastanawiałem nad tym i pewnie robiłem String += (...) :).
Pozdrawiam

0

@Billy

  1. Ja dokładniej mierzę czas (System.nanoTime()).
  2. Ty mierzysz łączny czas przetwarzania i pisania na ekran, ja tylko czas przetwarzania.
0

zgadza się, problem występuje tylko gdy odczytuje pliki *.txt przez notatnik windowsa

0
bo napisał(a)

@Billy

  1. Ja dokładniej mierzę czas (System.nanoTime()).
  2. Ty mierzysz łączny czas przetwarzania i pisania na ekran, ja tylko czas przetwarzania.

nie żebym się czepiał, tylko tak prostuję ;), rzeczywiście nie pomyślałem o różnicach nawet przy takich działaniach jak wypisywanie, dwa, że nie wiem czemu currentTimeMillis aż tak przekłamał (w przeliczeniu z nanoTime, który daje ~9ms, currentTimeMillis ~16ms). No mniejsza, usprawniłem, sprawdziłem, i dalej nie jest w stanie przekroczyć 4k ilorazu ;D. Dobra, zrzućmy to na różnicę maszyn, nie o tym temat ;).
Pozdro,

0

Winodows zawsze podaje niedokładnie, gdy się go pyta o milisekundy...

0

Zauważyłem ciekawy objaw. Po kompilacji z ręki kompilatorem suna (javac ... w konsoli) stosunek czasów jest około 6000, po kompilacji projektu w Eclipse stosunek czasów jest około 3000 (przy uruchamianiu w Eclipse i przy uruchamianiu ręcznym). Czas dla StringBuffer jest praktycznie taki sam, dla String jest dwa razy krótszy.

0

To dlatego ze eclipse ma wlasny kompilator, nie uzywa javac. Poza tym, eclipse domyslnie kompiluje z debugiem, w javac musisz to specjalnie wlaczyc.

0

Zacząłem badania terenowe: skopiowałem program na pendrive'a i uruchamiam go na każdym napotkanym komputerze z JVM. Przed chwilą (kiepski komputer: XP Pro, 120MB RAM-u, Intel Celeron) uzyskałem stosunek czasów ponad 30 tys. Czas wykonania dla konkatenacji Stringów to ponad pół godziny.
@up, ja wiem, że Eclipse ma własny kompilator. Ciekawe jest to, że wygenerowany przez Eclipse kod jest
dla pewnych pętli dwukrotnie szybszy a dla innych tak samo szybki.

0

Widocznie kompilator eclipsa jest madrzejszy jesli widzi konkatenacje Stringow.

0

Cześć

Zamiast '\n' zastosuj '\r'

p.s. nie trać czasu na programowanie ;)

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