Advanced: Datei Zeilenweise auslesen

  • Antworten:9
Gelöschter Account
  • Forum-Beiträge: 5.136

08.05.2011, 01:02:17 via Website

Da es viele Anfragen gab, wie eine Datei Zeile für Zeile ausgelesen werden kann möchte ich hier noch mal eine Methode vorstellen die das einfach und vor allem schnell erledigt.

public String readTextFile(String myFile) {
String DEBUG_TAG = "inside_readTextFile";
String line = "";
StringBuffer sb = new StringBuffer();



try {
// File zum Lesen oeffenen
FileInputStream in = new FileInputStream(myFile);

// Wenn das File existiert
// zum einlesen vorbereiten
InputStreamReader input = new InputStreamReader(in);
BufferedReader buffreader = new BufferedReader(input);


// Die Datei zeilenweise einlesen und in sb appenden
// Der appender wird hier benutzt um das ganze zu beschleunigen
// Operation mit + wäre hier viel zu langsam.


try {
while ((line = buffreader.readLine()) != null) {
//Log.d(DEBUG_TAG, "LogLine: " + line);
sb.append(line);
//sb.append(line).append("\n"); // Diese Version haengt noch einen Line Separator (Line Feed) hinten dran.
}

} catch (Exception e) {
e.printStackTrace();
Log.d(DEBUG_TAG, "Error reading Line from File: " + e.getMessage());

}

try {
in.close();
} catch (Exception e) {
e.printStackTrace();
Log.d(DEBUG_TAG, "Error closing File: " + e.getMessage());

}


} catch (java.io.FileNotFoundException e) {
e.printStackTrace();
Log.d(DEBUG_TAG, "File not found: " + e.getMessage());

}

return sb.toString();
}

Der Vorteil ist hier unter anderem die Geschwindigkeit die durch Verwendung des StringBuffers anstelle einer üblicherweise verwendeten normalen Concatenation mit Hilfe des "+" Zeichens zustande kommt.

Darüber hinaus werden die Fehler entsprechend abgefangen und ausgegeben.

Der Aufruf der Methode erfolgt beispielsweise so:

String meinFile = readTextFile("/sdcard/old_batman.txt");

0,35 MByte werden mit dieser Methode in etwa 0,31 Sek. eingelesen.

— geändert am 08.05.2011, 14:35:05

lg Voss

Ludwig H.

Antworten
Ludwig H.
  • Forum-Beiträge: 3.256

08.05.2011, 13:40:54 via Website

Vielen Dank erstmal für den tollen Codeschnipsel!
Es funktioniert auch alles, die Zeilen werden eingelesen und im Log ausgegeben.
Nur das "return sb.toString();" macht mich ein bisschen stutzig. wie heißt denn der String der da erzeugt wird?

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

08.05.2011, 13:48:52 via Website

Wie der heißt legst Du beim Aufruf der Methode fest.

Das "return sb.toString()" wandelt zunächst den StringBuffer sb mit der Methode toString() in einen String um und schiebt das Ergebnis dann in den beim Aufruf der Methode angegebenen String.

So wie ich es auch oben in : "Der Aufruf der Methode erfolgt bspw. so" bereits beschrieben habe.

lg Voss

Ludwig H.

Antworten
Ludwig H.
  • Forum-Beiträge: 3.256

08.05.2011, 14:05:12 via Website

Super, vielen Dank!
Wenn ich die Ausgabe jetzt an eine TextView übergebe, wird die Datei aber "unformatiert" ausgegeben. Also einfach der ganze Text nacheinander.
Bsp: Eingabedatei:
1Zeile 1
2Zeile 2
3Zeile 3
Ausgabe:
1Zeile 1Zeile 2Zeile 3
Kann man das noch ändern?

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

08.05.2011, 14:14:45 via App

Hm,
man könnte in der while-Schleife einen LineSeperator "appenden" also zB
1sb.append("\n");
Hier gab es noch irgendeine Möglichkeit sich ihn vom System mitteilen zu lassen.. Aber bei mir klappt "\n" immer. Ich denke, wenn man eine Textdatei so schreibt und dann auf Windows öffnet, sind die Zeilenumbrüche fehlerhaft..
Lg Ansgar

— geändert am 08.05.2011, 14:15:13

Ludwig H.

Antworten
Ludwig H.
  • Forum-Beiträge: 3.256

08.05.2011, 14:18:50 via Website

Super, Dankeschön, das funktioniert! :)

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

08.05.2011, 14:28:17 via Website

Ahhh Ansgar war schneller ... :)

Eleganter gehts so:
sb.append(line).append("\n");

Was im Endeffekt genau das ist was Ansgar halt auch macht .. nur gleich in einem Rutsch.

Unter Windows besteht ein Zeilen umbruch glaube ich immer aus "\r\n" und nicht nur aus "\n" ...

lg Voss

Antworten
Gandalf the Gray
  • Forum-Beiträge: 2

29.04.2014, 11:26:05 via Website

Hallo,

hab den Code ausprobiert. Leider bekomme ich immer eine FileNotFoundException. In welchem Verzeichnis muss die Datei liegen (Pfadangabe)?

Antworten
impjor
  • Forum-Beiträge: 1.793

29.04.2014, 13:49:31 via App

Das Tut ist ja schon ein bisschen "eingestaubt".

Statt StringBuffer kann hier getrost StringBuilder verwendet werden, und den Pfad "/sdcard/" sollte man nicht mehr benutzen.

Ist deine Datei auf der SD-Karte gespeichert kannst du mit Environment#getExternalStorageDir() den Pfad geben lassen. Ist die Datei im /assets/ Ordner von der apk musst du statt FileInputStream in = ...
InputStream in = getAssets().open("";)
benutzen. Wenn in res/raw gespeichert entsprechend openRawResource(R.raw.blub); verwenden.

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten