# Datei öffnung sehr langsam



## Die4Me (8. Mai 2006)

Hallo,
ich versuche bei mir eine Datei zu öffnen, welches doch nur sehr langsam passiert.
Für eine Datei bei ca 300kb braucht er ne gute minute.
nun, hier erstmal der Quellcode:

```
/**
     * countLines() - Zählt die Zeilen einer Datei
     * 
     * @return      int
     */
    public int countLines ()
    {
        try
        {
           FileReader fr = new FileReader (dateiname);
           BufferedReader br = new BufferedReader (fr);
           int res = 0;
           String line;
           do
           {
             line = br.readLine();
             res++;
           }
           while (line != null);
           br.close ();
           fr.close ();
           return res-1;
        }
        catch (IOException e)
        {
          return -1;
        }
    }

    /**
     * loadData() - läd eine Datei in ein Feld
     * 
     * @return  boolean
     */
    public boolean loadData ()
    {
        try
        {
            int cl = countLines();
            data = new String[cl];
            FileReader fr = new FileReader (dateiname);
            BufferedReader br = new BufferedReader (fr);
            for (int i = 0; i < cl; i++)
            {
                data[i] = br.readLine();
            }
            br.close();
            fr.close();
            return true;
        }
        catch (IOException e)
        {
            return false;
        }
    }
```
Meines erachtens brauche ich ein Array, weil es sich hier um Datensätze handelt, wobei ein Datensatz jeweils in einer Zeile steht.
Wäre nett, würdet ihr euch das mal nagucken...
thx


----------



## The_S (8. Mai 2006)

Verwende eine Collection, dann kannste dir das zweimalige auslesen schenken. Aber daran dürfte es theoretisch auch nicht liegen. Wie hast du festgestellt, dass das auslesen 1 Minute dauert?


----------



## Die4Me (8. Mai 2006)

Naja...
ich lasse doch einen rückgabewert geben.
Diesen lasse ich über ein gui ausgeben.
Also, nach meiner kenntnis kann der auch erst ausgegeben werden, wenn die Datei vollständig ausgelesen ist...
oder irre ich da???


----------



## Murray (8. Mai 2006)

Bau doch direkt vor dem Einlsen mal folgende Zeile ein:

```
long t0 = System.currentTimeMillis();
```

Und nach dem Einlesen dann:

```
System.out.println( (System.currentTimeMillis() - t0) +  " ms");
```

Dann siehst Du genau, wie lange die Sequenz dauert.


----------



## The_S (8. Mai 2006)

ja klar, aber kann ja sein, dass du danach noch was anderes machst, die Datei z. B. in einem JTextArea o. ä. anzeigen und noch ein paar Operationen daran machst.


----------



## Die4Me (8. Mai 2006)

@Murray: sry, ich bin gerade nich so bewandert.
ich baue dies zum Zeit auslesen erstens am anfang in den try Zweig und dann noch am ende des try-Zweiges ein.
BlueJ sagt: Unreachable Statement.
komisch.

@Hobbit_Im_Blutrausch: Danach wird das alles, was ich ausgelesen habe noch einmal an den Kommas getrennt (fast wie CVS).
Ich lass aber nur das laden durch gehen...


----------



## Die4Me (8. Mai 2006)

@Murray: mein Fehler....
hatte dies hinter em return...
ansonnsten 51407 ms


----------



## Roar (8. Mai 2006)

bei mir braucht der code noch lange nichtmal eine sekunde - und das für eine 6,5mb datei.
entweder du brauchst nen neuen computer/festplatte oder du verheimlichst uns code :roll:


----------



## Die4Me (8. Mai 2006)

ich habe eben gerade was mitbekommen.
die variable cl brauche ich zwei mal.
ich habe noch eine ältere version, wo ich versehentlicherweise noch countLines() beide male benutze, nicht zu anfang cl initialisiere und dann speichere...
sry, ist mein Fehler.


----------



## Die4Me (8. Mai 2006)

so, aber nu noch eine kleine Frage.
da ich ja gerade dort geirrt hab.
Wir arbeiten dort mit auch vielen Datensätzen, wo in einer Datei auch schon mal 2Mio oder mehr datensätze drine stehen (gps).
Wie kann ich dieses problem umgehen?


----------



## Roar (8. Mai 2006)

auch bei 2 millionen zeilen (45,5mb) dauert das auslesen "nur" 10 sekunden.

als erstens würd ich mal meinen code reparieren. die methode countLines() ist überflissig. dann nimm nio statt BufferedReader

warum verwendest du denn keine datenbank? :autsch:


----------



## Die4Me (9. Mai 2006)

sry, von nio hab ich noch nix gehört.
Ich meinte nur damit, dass der Integer-Bereich doch irgendwann erschöpft ist. Damit auch das array.
Wir nutzen dazu Datenbanken.
Nur müssen wir die Daten dazu ersteinmal aufarbeiten.
d.h. wir müssen diese erst auslesen, auch wenn diese mehr als 2 Mio Datensatze haben und dann in die Db schreiben.
Erst wenn diese in der DB stehen werten wir aus.


----------



## Roar (9. Mai 2006)

keine sorge, ein integer kann noch ein bisschen mehr als 2 mio speichern..

die daten aus der datei auszulesen dauert nur wenige sekunden. wahrscheilnich dauert das noch was länger die in die datenbank einzufügen, jenachdem welche db, treiber, hardware...


----------



## Die4Me (9. Mai 2006)

ich nutze die jdbc - treiber mit einer MySQL anbindung.
Dabei nutzen wir den MySQL Connector J direkt von mysql, der dort angeboten wird.
Ich denke mal, dieser wird schon schnell genug sein... ^^


----------



## padde479 (30. Mai 2006)

Im obigen Quellcode würde ich eine einfache while-Schleife anstelle einer do-while-Schleife verwenden. Das dürfte einiges an Geschwindigkeit bringen. Ein kleines Beispiel:


```
import java.io.*;	// Alle Klassen aus dem Package java.io importieren


class Textfile {
	private File file;
	
	public Textfile (String filename) {
		file = new File (filename);
	}
	
	public int berechneAnzahlWoerter () throws IOException {
		int nWoerter = 0;  // Wörterzähler initialisieren
			
		// FileReader erstellen:
		FileReader fr = new FileReader (file);
		// BufferedReader davor schalten:
		BufferedReader in = new BufferedReader (fr);
			
		// Zeilen nacheinander lesen:
		String zeile;
		while (true) {
			zeile = in.readLine();
			if (zeile == null) break;	// Ende der Datei erreicht!
			// Nun die Zeile zerlegen:
			String[] woerter = zeile.split("\\s");
			nWoerter += countWords (woerter);	// Wörter zählen
		}
			
		// Datei schließen:
		in.close();  // Schließt ebenfalls den FileReader!
		return nWoerter;
	}
	
	
	private int countWords (String[] sarr) {
		// Alle leeren Strings nicht mitzählen:
		int n = 0;
		for (int i=0; i<sarr.length; ++i) {
			String wort = sarr[i];
			if (!wort.equals("")) n++;
		}
		return n;
	}
}
```

Viel Spaß weiterhin...


----------



## The_S (30. Mai 2006)

1. Wenn in einer schleife ne Datei lesen, dann bitte so


```
while ((zeile = in.readLine()) != null) {
```

2. Warum soll bitte ne while-Schleife so viel schneller sein als ne do-while?


----------



## Leroy42 (30. Mai 2006)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> 2. Warum soll bitte ne while-Schleife so viel schneller sein als ne do-while?



Na das liegt doch wohl auf der Hand:

Weil der Schleifenkörper eventuell 0 mal, also immerhin bis zu einem ganzen Mal
weniger durchlaufen wird.

Also wirklich, du kannst Fragen stellen...  ???:L 


[schild=5 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Wer ein paar Ironie-Tags herumliegen hat: Immer her damit! Meine sind irgendwie nicht auffindbar.[/schild]


----------



## The_S (30. Mai 2006)

[ironie][/ironie] *rüberreich*


----------

