PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] Hochperformantes Dateihandling


Senior Sanchez
2007-06-14, 21:12:21
Hi,

Ich brauche sehr schnelles Dateihandling. Ich will eine große Datei einlesen (momentan 14 MB, aber auch 140 MB groß). Da drin stehen mehrere Strings, wobei jeder String in seiner eigenen Zeile steht.

Mittels java.io.* ist das ja kein Ding, aber ich würde das gerne über MemoryMappedIO abwickeln.


FileInputStream fin = new FileInputStream(args[0]);
FileChannel in = fin.getChannel();

MappedByteBuffer input = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());

array = new String(input.asCharBuffer().toString()).split("\n");


Das funktioniert alles sehr gut bis auf das split. Er will mir partout nicht nach linefeeds splitten. Können diese beim Einlesen verloren gegangen sein? Oder was mache ich dann falsch?

Danke

Grestorn
2007-06-14, 21:23:13
Hi,

Ich brauche sehr schnelles Dateihandling. Ich will eine große Datei einlesen (momentan 14 MB, aber auch 140 MB groß). Da drin stehen mehrere Strings, wobei jeder String in seiner eigenen Zeile steht.

Mittels java.io.* ist das ja kein Ding, aber ich würde das gerne über MemoryMappedIO abwickeln.


FileInputStream fin = new FileInputStream(args[0]);
FileChannel in = fin.getChannel();

MappedByteBuffer input = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());

array = new String(input.asCharBuffer().toString()).split("\n");


Das funktioniert alles sehr gut bis auf das split. Er will mir partout nicht nach linefeeds splitten. Können diese beim Einlesen verloren gegangen sein? Oder was mache ich dann falsch?

Danke

Du liest die Datei als Binärdatei (obwohl sie wahrscheinlich ASCII enthält) und suchst darin nach einem UNICODE Zeichen ("\n"), das so in der Datei nicht vorkommt (da es in Unicode 2 Byte kodiert wird).

Deswegen verwendet man in Java eben üblicherweise Reader und Writer um Textdateien zu lesen und zu schreiben. Die kümmern sich um die Umsetzung zwischen ASCII, Unicode, UTF-8 usw.

Senior Sanchez
2007-06-14, 21:30:39
Du liest die Datei als Binärdatei (obwohl sie wahrscheinlich ASCII enthält) und suchst darin nach einem UNICODE Zeichen ("\n"), das so in der Datei nicht vorkommt (da es in Unicode 2 Byte kodiert wird).

Deswegen verwendet man in Java eben üblicherweise Reader und Writer um Textdateien zu lesen und zu schreiben. Die kümmern sich um die Umsetzung zwischen ASCII, Unicode, UTF-8 usw.

Wenn ich aber einen Aufruf an den CharBuffer mache, erwarte ich eigentlich, dass das auch als Unicode gehandled wird. Und was sollen die Reader intern großartig anders machen?

Und jede Datei wird erstmal als binäre Datei gelesen, wie sollte es auch anders gehen. Es entscheidet dann lediglich die Interpretation der Daten was es ist und wie gesagt, beim CharBuffer denke ich, dass der das schon richtig handlen sollte.

Grestorn
2007-06-14, 21:32:51
Wenn ich aber einen Aufruf an den CharBuffer mache, erwarte ich eigentlich, dass das auch als Unicode gehandled wird. Und was sollen die Reader intern großartig anders machen?
Da erwartest Du falsch.

Mit dem CharBuffer sagst Du, "der ByteBuffer enthält bereits Unicode, behandle es bitte auch so!". Also prinziell eine Art Cast.

Mit einem Debugger siehst Du den Effekt übrigens sofort.

Hamud
2007-06-14, 21:46:48
Es macht wenig sinn, eine 140MB Datei in einen String zu schreiben, um ihn dann mit split zu zerhaken. Für den String brauchst du 280MB(angenommen ascii kodierung) Ram. Und das schlimmste dadran ist, es muss ein zusammenhängendes stück sein. Wenn eine Java VM erstmal eine Weile läuft ist das fast ein ding der unmöglichkeit.

Nimm lieber einen BufferedReader, und lies die nächste Zeile mit readline().

Senior Sanchez
2007-06-14, 21:48:13
Stimmt, lauter komische Zeichen drin (japanische um genau zu sein).

Wie bekomme ich das dann anders hin? Das muss doch auch über nio gehen.

Grestorn
2007-06-14, 21:54:18
Stimmt, lauter komische Zeichen drin (japanische um genau zu sein).

Wie bekomme ich das dann anders hin? Das muss doch auch über nio gehen.

Wie Hamud schreibt: BufferedReader macht alles, was Du brauchst.