# Text Datei einlesen



## qtuan3008 (18. Aug 2011)

Hallo liebe Mitprogrammierer.

Ich habe eine Textdatei ca. 500MB, 12.000.000 Zeile
Zum Einlesen benutze ich BufferedReader


```
public void doctext_Seite_Redirect() {
		String line = "";
		int count =0;
		try {
			BufferedReader reader = new BufferedReader(new FileReader(
					"..........."));
			while (line != null) {
				count++;
				line = reader.readLine();
			}			
			System.out.println(count);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
```

Das Problem ist: der Programm läuft langsam 12min aber noch nicht fertig. Gibt vielleicht andere Lösung außer BufferedReader zum Einlesen?

Viele Grüsse
Tuan


----------



## SlaterB (18. Aug 2011)

hast du den Code exakt so?
oder machst du mit der Linie noch etwas, wenn du alle Strings mit + zusammenaddierst kann es unendlich langsam werden,
für jede einzelne Zeile müssen dann hunderte MB im Speicher neu beschrieben werden (Lösung: StringBuilder)
anderenfalls sollte es ganz fix gehen,

hier ein Testprogramm:
erzeugt sich die Datei gar selber, schreibt aktuell 5 Mio. Zeilen = 90 MB, das dauert bei mir 5.5 sec,
liest danach diese 5 Mio. Zeilen in 1.5 Sekunden ein,

wenn das Testprogramm bei dir ähnlich schnell ist, dann macht dein restlicher Code irgendwas anders,
wenn auch langsam, dann besteht wirklich ein Problem


```
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        File f = new File("test.txt");
        long time = System.currentTimeMillis();
        int max = 1000000 * 5;
        String line = "Hallo Hallo Hallo\n";
        BufferedWriter b = new BufferedWriter(new FileWriter(f));
        for (int i = 0; i < max; i++)
        {
            b.write(line);
        }
        b.close();
        System.out.println("file size: " + f.length() + ", time: " + (System.currentTimeMillis() - time));

        int count = 0;
        BufferedReader reader = new BufferedReader(new FileReader(f));
        while (line != null)
        {
            count++;
            line = reader.readLine();
        }
        System.out.println(count + ", time: " + (System.currentTimeMillis() - time));
        reader.close();
    }
}
```


----------



## qtuan3008 (18. Aug 2011)

danke für schnellen Antwort.
Ich habe deine Code probiert aber mit langem String. Es ist klar langsamer. Gibt vielleicht andere Methode außer BufferedReader. Wenn nicht, dann muss ich damit leben.


----------



## SlaterB (18. Aug 2011)

welche Zeiten ergeben sich denn wenn du mein Programm unverändert ausführst?

was bedeutet
> aber mit langem String. Es ist klar langsamer.
ganz konkret?

hast du schon eine fertige Zeit gemessen für deine lange Datei? 
ist die Zeit linear, brauchst du also für eine 250 MB-Datei, falls vorhanden, genau die halbe Zeit oder zufällig 1/4?
wenn alles zu lang zum Testen ist dann mit kleinen Dateien anfangen, 1 KB, 1 MB, 2 MB usw. 

eine Alternative ist vielleicht nio statt io:
Example Depot | Useful code samples
aber ich persönlich kann mir nicht vorstellen, dass es am BufferedReader liegt


----------



## qtuan3008 (18. Aug 2011)

ich meine bei dir du hast mit dem String = "Hallo Hallo Hallo\n" probiert. ich habe mit String = "Hallo Hallo Hallo Hallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo Hallo" probiert und ist langsamer. Das ist Normal oder wenn das String länge ist
Was ich euch fragen möchte gibt andere Methode zum Einlesen die schneller als Bufferreader funktioniert? Wenn nicht dann kann ich nicht anders machen.


----------



## SlaterB (18. Aug 2011)

ich hab mein Posting bisschen editiert, deshalb nochmal ein Hinweis darauf falls du den nio-Link nicht gesehen habe,

da du mit 'langsamer' weiter spekulativ bleibst erlaube ich mir auch dazu nochmal eine Bemerkung:
klar wird das ganze deutlich langsamer wenn der String länger wird, die Datei dann auch z.B. 300 MB statt 90 MB belegt,
bei mir dauert das Einlesen dann auch schon mal 10 sec statt 2 sec oder ähnliches,
aber das ist ja überhaupt kein Problem, mehr als 50-100 MB pro Sekunde sollte man nicht annehmen,
und von deinen 12 Min. sind das noch Welten entfernt,
selbst das Betriebssystem braucht zum Kopieren einer derartigen Datei paar Sekunden, und wenn Java das noch alles in den Speicher laden sowie Millionen String-Objekte erzeugen soll..

> ich habe mit String = "Hallo Hallo Hallo Hallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo Hallo" probiert 

solltest du keinen Zeilenumbruch, also insgesamt nur eine Zeile haben, kann das vielleicht Probleme machen, teste ich jetzt noch,
bzw. kann ich gar nicht ohne erst noch den Speicher zu erhöhen usw., hast du daran gedacht?
vorher sprachst du ja von Millionen Zeilen, nicht von EINER..


----------



## qtuan3008 (18. Aug 2011)

Ich habe hier die Datei die ist leide in .bz2 kompriemiert. Kannst du vielleicht probieren wie lange bei dir dauert (nur zum einlesen)


----------



## SlaterB (18. Aug 2011)

siehe wieder meinen edit zum Zeilenumbruch, teste das lieber selber


----------



## qtuan3008 (18. Aug 2011)

Ich habe eine Datei 72mb probiert, dauert 5 min denke für 500mb 40 min.
Ich denke ich muss mit Bufferreader leben. Und den Rechner Warten. trotzdem danke für deine Hilfe.


----------



## SlaterB (18. Aug 2011)

mir unverständlich dass du so früh und unkoordiniert aufgibst,
du müsstest mein Programm nur kopieren und ausführen,
wenn dass dann auch lange dauert (genau zu unterscheiden zwischen Speichern und Laden), 
dann wäre das ein Phänomen was ich bisher nicht gesehen habe, also für sich bemerkenswert,

wenn es dagegen schnell geht, dann bestände ja ein Ausgangspunkt um den Rest weiter zu erforschen,
dann würde ich vielleicht auch die Datei laden und anderes, aber du machst nicht mit, na dann eben nicht


----------



## Dit_ (18. Aug 2011)

ich glaube es dauert bei dir so lange wegen 
	
	
	
	





```
System.out.println(count);
```


----------



## SlaterB (18. Aug 2011)

ist das eine Spaßmeldung oder willst du das noch erläutern?


----------



## qtuan3008 (18. Aug 2011)

@Dit:wegen 
	
	
	
	





```
System.out.println(count);
```
 bestimmt nicht
@SlaterB: danke für deine Mühe. Ich lasse mein Programm jetzt laufen. Ich denke der läuft langsam weil die Zeile von mir sind lang z.b: "Government of the Northern Territory||||Local Government Areas of the Northern Territory".


----------



## SlaterB (18. Aug 2011)

wie du meinst, für die Allgemeinwelt gilt aber:
auch lange Zeilen (im Sinne von < 1000 Zeichen, nicht > 1 Mio..) ändern nichts,
mein Programm mit 

```
int max = 1000000 * 2;
        String line = "Hallo Hallo Hallo Hallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo Hallo\n";
```
(zu beachten ist der Zeilenumbruch am Ende)

erstellt eine 380 MB-Datei, die in 5 sec eingelesen ist


----------



## qtuan3008 (18. Aug 2011)

Ich habe mit deinem String probiert. Und der Rechner ergibt 
file size: 378000000, time: 39791
2000001, time: 76984 
also 76s zum einlesen.
Ich benutzer eclipse. Prozessor 2.5ghz 
Kann sein dass ich in eclipse etwas konfiguieren muss?


```
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class test {
	public static void main(String[] args) throws Exception {
		File f = new File("test.txt");
		long time = System.currentTimeMillis();
		 int max = 1000000 * 2;
	        String line = "Hallo Hallo Hallo Hallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo HalloHallo Hallo Hallo\n";
		BufferedWriter b = new BufferedWriter(new FileWriter(f));
		for (int i = 0; i < max; i++) {
			b.write(line);
		}
		b.close();
		System.out.println("file size: " + f.length() + ", time: "
				+ (System.currentTimeMillis() - time));

		int count = 0;
		BufferedReader reader = new BufferedReader(new FileReader(f));
		while (line != null) {
			count++;
			line = reader.readLine();
		}
		System.out.println(count + ", time: "
				+ (System.currentTimeMillis() - time));
		reader.close();
	}

}
```


----------



## SlaterB (18. Aug 2011)

da die ersten 40 sec fürs Schreiben sind brauchst du nur 37 sec zum Lesen,
das ist nochmal die Häfte weniger, aber immer noch erstaunlich mehr als bei mir,

dennoch würde ich über diesen Wert gar nicht aufregen, das ist doch schon toll gegenüber 12 Min. oder noch längere unbekannte Zeit,
da muss man eigentlich auch nicht groß was untersuchen (ok, nicht zuletzt weil mir eh kaum was einfällt  )

lasse das Schreiben weg und gib den Pfad zu deiner 500 MB-Datei an, die sollte doch in diesem Programm in 1-2 Min geschafft werden?
ein kleiner Zusatz ist noch eine Ausgabe während der Schleife, z.B.

```
if (count % 100000 == 0) System.out.println(count + ", time: " + 
                     (System.currentTimeMillis() - time) + ", running");
```


---------

wie schnell geht eigentlich das Kopieren der Datei im Explorer, falls Windows?
gibt es Virenscanner, Firewall oder irgendwas vom Betriebssystem zu bedenken?
zufällig von einer USB-Festplatte gelesen?..


----------



## qtuan3008 (18. Aug 2011)

Ich habe auch nicht verstanden warum gibt den Unterschied 5s vs 40s. Oder dein Rechner ist stark??????
"lasse das Schreiben weg und gib den Pfad zu deiner 500 MB-Datei an" Ich habe nicht wirklich verstanden was du gemeint hast. Meinst du es kann liegen an den Pfad.


----------



## SlaterB (18. Aug 2011)

die 5 zu 40 sec kann ich bisher auch nicht erklären, finde sie aber wie gesagt weitaus besser als 40 sec zu 40 Min.,

am Pfad liegt es eher nicht, sondern du sollst dieses Programm nun mit deiner 500 MB-Datei testen, ob diese immer noch 40 Min. braucht oder hier schneller geht,
dabei dann den Anfang mit Schreiben einer Datei offensichtlich weglassen


----------



## qtuan3008 (18. Aug 2011)

Ja ich habe schon getestet. Ich habe nicht bis 40min gewartet sondern 10min. Hast du meine Datei probiert. Die ist nur text datei, mehr nicht also brauchst du keine sorge.

Wenn wir keine Lösung finden können, kann du mir bescheid sagen, dann werde ich das Thema erledigen.
Und ich muss dir noch mal danke für deine Mühe


----------



## Shulyn (18. Aug 2011)

qtuan3008 hat gesagt.:


> Ich habe mit deinem String probiert. Und der Rechner ergibt
> file size: 378000000, time: 39791
> 2000001, time: 76984



Habe es auch mal laufen lassen...

```
file size: 378000000, time: 4663
2000001, time: 7896
```

Schon sehr komisch das du SO lange brauchst...


----------



## Andi_CH (18. Aug 2011)

Beginnt die langsame Kiste möglicherweise zu swappen?
Das würde vieles Erklären ...


----------



## qtuan3008 (18. Aug 2011)

Ich denke es hängt an dem Rechner ab, java, eclipse. Ich benutze momentan den Rechner von der uni. Der ist relativ schnell aber kann sein dass der alte java hat.


----------



## SlaterB (18. Aug 2011)

ich kann die Datei erst abends testen


----------



## qtuan3008 (18. Aug 2011)

hier ist meine Datei Katagorie_Seite_bz2.bz2 die ist leide in .bz2 komprimiert


----------



## Andi_CH (18. Aug 2011)

Vergiss "schnelle" Rechner - die schnellste CPU wird ausgebremst, wenn die Kiste zu wenig Memory hat und swappt.
Altes Java? Dann hol dir doch das Neue - das kann man IMO auch als gewöhnlicher User irgenwohin kopieren und dann dem Eclipse sagen, dass es das verwenden soll (Ist allerdings mehr Erinnerung als Wissen)


----------



## qtuan3008 (18. Aug 2011)

der Rechner ist von der uni Speicher 8gb Swap 4gb

Ich habe gerade probiert mit meinem Laptop


```
file size: 378000000, time: 8348
2000001, time: 13265
```

???:L???:L???:L???:L


----------



## Dit_ (18. Aug 2011)

SlaterB hat gesagt.:


> ist das eine Spaßmeldung oder willst du das noch erläutern?



nein, bloß Quatsch... habs übersehen dass die Anweisung außerhalb der while schleife ist...

@qtuan3008
axoooooo dann hast du bestimmt eine Netzwerkfestplatte...

Detailierte SystemInformationen könnte man gleich am Anfang posten


----------



## qtuan3008 (18. Aug 2011)

@Dit ja du hast recht. Ich habe Netzwerkfestplatte. 
Ich bin Neuling bei der Programmierung.


----------

