uepselon: Schnelles lesen einer Datei.

Hallo,

ich versuche gerade eine Textdatei in ein JTextPane zu laden.
Bisher hab ich folgendes gemacht:

try
               {
               BufferedReader in = new BufferedReader(new FileReader(FileName));
               do
                {
                line = in.readLine();
                if (line != null)
                   {
                   all_lines+=line+"\n";
                   }
                }
               while (line != null);
               }
             catch (Exception e) { }

all_lines hab ich dann in das Document des TextPanes über insertString(..) eingefügt.

Das ganze funktioniert auch, aber viel zu langsam.
Bei kleinen Textdatei fällt es kaum auf, aber ab 500 Zeilen Text, wird die Wartezeit recht nervig (3sec aufwärts). Wie kann ich das optimieren?

Gruß,
ueps

  1. Hallo,

    Das ganze funktioniert auch, aber viel zu langsam.
    Bei kleinen Textdatei fällt es kaum auf, aber ab 500 Zeilen Text, wird die Wartezeit recht nervig (3sec aufwärts). Wie kann ich das optimieren?

    Woran liegt es denn? Hast du mal Tests gemacht, ob's am Einlesen oder
    am insertString() liegt? Naja, vermutlich am InsertString... Mußt du
    den Text wirklich zeilenweise zum Document hinzufügen, oder kannst
    du den gesamten Text evtl. per setText(String) (er)setzen? Wenn du
    insertString brauchst (und bei setText), dann bau dir doch vorher den
    einzufügenden String komplett zusammen (indem du alle eingelesenen
    Strings über einen StringBuffer aneinanderfügst) und füge den Gesamt-
    String einmalig ein (oder setze ihn via setText).

    Was anderes fällt mir auf die Schnell nicht ein.

    Gruß
    Slyh

    --
    Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.
    1. Hallo,

      Wenn du
      insertString brauchst (und bei setText), dann bau dir doch vorher den
      einzufügenden String komplett zusammen (indem du alle eingelesenen
      Strings über einen StringBuffer aneinanderfügst) und füge den Gesamt-
      String einmalig ein (oder setze ihn via setText).

      Das mach ich ja, ich lese die Datei Zeilenweise ein und füge die Zeilen dem String all_text hinzu. Diesen schreibe ich dann in einem Rutsch ins Document vom TextPane. Aber wie geasgt bei größeren Dateien dauert das ewig.

      Gruß,
      ueps

      1. Hallo,

        Das mach ich ja, ich lese die Datei Zeilenweise ein und füge die Zeilen dem String all_text hinzu.

        Ooh, ups, da hab ich mal wieder nicht genau genug geguckt. Dann wäre
        mir auch nur der Vorschlag von Martin eingefallen. (Also StringBuffer.)
        Mmh...

        Gruß
        Slyh

        --
        Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.
  2. Hi,

    all_lines+=line+"\n";

    Benutze StringBuffer!!!

    Wenn es dann immer noch zu langsam abläuft, melde Dich wieder.

    Viele Grüße,
    Martin Jung

    1. Hallo,

      Benutze StringBuffer!!!

      Hab ich jetzt auch mal versucht, dauert aber bei 800 Zeilen immernoch 2 sec bis die Datei geladen ist. In einem "normalen" Editor lädt sowas in einem Bruchteil einer Sekunde.

      Gruß,
      ueps

      1. Hi,

        Hab ich jetzt auch mal versucht, dauert aber bei 800 Zeilen immernoch 2 sec bis die Datei geladen ist. In einem "normalen" Editor lädt sowas in einem Bruchteil einer Sekunde.

        Ich kann mich jetzt zunächst nur Slyh anschließen: Welche Ursache für die mangelnde Performance ergibt Deine Analyse? Liegt es am Einlesen der Datei? Liegt es an den Methoden der Swing-Klasse(n)? Oder liegt es vielleicht an etwas anderem?

        Bei folgendem Code (ungetestet), erspart man sich noch eine Bool'sche Auswertung pro Schleifenschritt (was Dein immenses Performancepoblem aber nicht lösen kann):
        try {
            BufferedReader in = new BufferedReader(new FileReader(FileName));
            StringBuffer buf = new StringBuffer();
            final String NL = System.getProperty("line.separator");
            while ( (line = in.readLine()) != null);
                buf.append(line);
                buf.append(NL);
            }
        catch (Exception e) { }

        Viele Grüße,
        Martin Jung

        1. Hallo,

          Ich kann mich jetzt zunächst nur Slyh anschließen: Welche Ursache für die mangelnde Performance ergibt Deine Analyse? Liegt es am Einlesen der Datei? Liegt es an den Methoden der Swing-Klasse(n)? Oder liegt es vielleicht an etwas anderem?

          also ich hab jetzt mal eine kleine Funktion geschrieben die die Zeit gemessen hat. Für das lesen der Datei in den StringBuffer brauchte meine Anwendung 90 ms, für insertString(0, fileData, mainAttr) sage und schreibe 661 ms!!! Warum dauert das solange?

          Gruß,
          ueps

      2. Hallo,

        Hab ich jetzt auch mal versucht, dauert aber bei 800 Zeilen immernoch 2 sec bis die Datei geladen ist. In einem "normalen" Editor lädt sowas in einem Bruchteil einer Sekunde.

        Du hast dann vermutlich sowas stehen:
          all_lines.append(line + "\n");

        Das ist schlecht, weil du oben wieder zwei Strings konkatenierst, so
        daß bei jedem Durchlauf zwei String-Objekte erzeugt (und dann wieder
        recycled) werden müssen.
          Ungefähr so: append(new String(line + new String("\n"));

        Also besser:
          all_lines.append(line).append("\n");

        Und das geht auf meinem Rechner dann rasend schnell.
        BTW: setText() ist doppelt so schnell wie insertString().

        Übrigens solltst du dir unbedingt mal die Java Code Conventions
        (http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html)
        durchlesen und dich möglichst dran halten.

        Gruß
        Slyh

        --
        Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.
        1. Hallo,

          Und das geht auf meinem Rechner dann rasend schnell.
          BTW: setText() ist doppelt so schnell wie insertString().

          hm, ich ich brauch mit insertString direkt aufs Document angewandt 661 ms, mit setText aufs TextPane 1873 ms?? 3 mal solange also.

          Übrigens solltst du dir unbedingt mal die Java Code Conventions
          (http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html)
          durchlesen und dich möglichst dran halten.

          werd ich mal machen.

          Gruß,
          ueps

  3. Hallo,

    Was willst Du machen? Einen einfachen Texteditor oder einen Editor für eine bestimmte Art Dokument (RTF, HTML ...)? Bist Du sicher, dass Du das Konzept von StyleContext, StyledDocuments und EditorKits verstanden hast?

    Schau Dir das mal an:
    http://www.spindoczine.com/sbe/

    Hier wird ein RTF-Editor gebaut:
    http://www.spindoczine.com/sbe/files/uts2/Chapter20html/Chapter20.htm
    Für den ersten Teil benötigst Du
    // Class SmallButton unchanged from section 12.4
    http://www.spindoczine.com/sbe/files/uts2/Chapter12html/Chapter12.htm
    und
    // Class SimpleFilter unchanged from section 14.1.9
    http://www.spindoczine.com/sbe/files/uts2/Chapter14html/Chapter14.htm
    !!Achtung!! im Quellcode von Chapter20 fehlt hierfür ein
    import javax.swing.filechooser.FileFilter;
    ;-))

    Dieser RTF-Editor lädt bei mir RTF-Dateien nur unwesentlich langsamer als Word.

    Einen einfachen Texteditor findest Du hier:
    http://www.oreilly.com/catalog/learnjava/chapter/ch14.html

    viele Grüße

    Axel

    1. Hallo Axel,

      Was willst Du machen? Einen einfachen Texteditor oder einen Editor für eine bestimmte Art Dokument (RTF, HTML ...)?

      Einen Editor zur Quelltextbearbeitung, d.h. die Daten sind eigentlich normaler Text der dann je nach Syntax gestyled wird.

      Bist Du sicher, dass Du das Konzept von StyleContext, StyledDocuments und EditorKits verstanden hast?

      Nicht so wirklich. Ich arbeite im Moment mit dem DefaultStyledDocument und diese Document wird direkt mit insertString gefüllt und anschließend einem TextPane übergeben.
      Auch der Syntax Style wird auf das Document mit setCharacterAttributes angewendet (im Moment nur Comments, da alles andere (z.B. Keywords...) die Perfomance beeinträchtigt).

      Da das ganze ein MultiDocument Editor ist, sind alle Documents und TextPanes in einer extra Klasse als Array untergebracht.

      Klasse multidoc;

      multidoc.setCurrentDoc(docnumber);
      multidoc.getDocument();
      multidoc.getTextPane();

      So in etwa lässt sich dann auf ein Document bzw. das TextPane zugreifen.

      Hier wird ein RTF-Editor gebaut:
      http://www.spindoczine.com/sbe/files/uts2/Chapter20html/Chapter20.htm

      Ich hab das auch mal versucht, EditorKit.read(instream, doc, 0)
      geht 1823 ms lang. Da ist meine Version mit insgesamt 700-800 ms doppelt so schnell. Aber eben im Vergleich zu einem kommerziellen Editor viel zu langsam.

      Gruß,
      ueps