Datei von hinten lesen

Status
Nicht offen für weitere Antworten.

reibi

Top Contributor
Hallo,

habe folgendes Problem: Ich möchte eine Datei einlesen, die aber gerade von einer anderen Applikation geschrieben wird. Die Datei kann ca. 5-10 MB an Grösse haben. Um herauszufinden ob die Datei vollständig geschrieben ist prüfe ich nach ob in der letzten Zeile ein "%%EOF"(also Markierung EndOfFile) steht. Um dies zu tun muss ich aber die Datei von oben nach unten mit readln durchparsen.

und zwar so:

Code:
		while((readLn=myBufferedReader.readLine())!=null) {
			if(readLn.indexOf("%%EOF")>-1) {
				returnValue=true;
			} // end if
		} // end while

Das dauert aber viel zu lange. DH ich möchte das gerne abkürzen und die Datei von hinten lesen.
Geht das irgenwie?

vielen Dank im voraus

reibi
 
Du kannst Zeilen überspringen, indem Du statt einem BufferedReader einen LineNumberReader verwendest.
 
Welchen Vorteil sollte den ein LineNumberReader hier gegenüber dem BufferedReader haben? Beide haben skip() ???:L
 
Danke für die schnelle Antwort: Aber skip() kann lediglich Zeichen überspringen, ich aber möchte das File von hinten lesen. Bei skip(long n) muss man ja angeben wieviel Zeichen man skippen will. Also ich weiss nicht einmal wieviel Zeilen ich überspringen will. Und wenn ich das wüsste, dann wüsste ich weiterhin nicht wie ich diese Zeilen überspringen kann.
 
Stimmt, an skip() habe ich gar nicht gedacht. Wenn man die Größe der Datei kennt, könnte man damit ja ans Ende der Datei springen und der Zeiger würde dann auf der letzten Zeile stehen. 🙂
 
@Byto:
Ich vermute mal du hast dich am Anfang auf LineNumberReader#setLineNumber() bezogen.
API hat gesagt.:
By default, line numbering begins at 0. This number increments as data is read, and can be changed with a call to setLineNumber(int). Note however, that setLineNumber(int) does not actually change the current position in the stream; it only changes the value that will be returned by getLineNumber().
 
Hoi, hab noch ne Info:

Also der Tip mit dem Skip ist gar nicht so schlecht, aber ich vermute dass er im Hintergund auch bloss die Dateio von oben bis unten durchliesst um dann an der Stelle anzuhalten.

Dies bringt mir auch kein Vorteil, weil das genau so lange dauert wie als ob ich die datei selbst durchparse.

Ich hab mal schnell die Zeiten gemessen, wie lange er für bestimmte Vorgänge braucht.

hier isses:

File erstellen dauerte, Sec : 0.02
FileReader erstellen dauerte, Sec : 0.0
BufferedReader erstellen dauerte, Sec : 0.0
length rausfinden dauerte, Sec : 0.0
Fillength = 3050342
skippen dauerte, Sec : 0.4
parsen dauerte, Sec : 0.0
Schliessen dauerte, Sec : 0.0
 
Natürlich muss er erstmal lesen(anders geht's nicht), aber skippen ist in jedem Fall schneller als readline, da keine String Objekte erstellet werden müssen.
btw: deine Zeitmessung ist mit ziemlicher SIcherheit Unsinn :wink:
 
Das kann sein bzw. ist so, aber selbst einem 3MB-File dauert es genau so lange wie StringOBJs mittels readLn einzulesen.

Hab da grad doch einen ZeitMessTest gemacht.

Zu erklären ist das für mich so: Bei einer StringOBJ_Befüllung macht er ja auch nichts anderes im Hintergrund als einzelne Zeichen zwischen den "\\n" auszuschneiden und in ein OBJ zu verpacken. Ich denke "skip()" macht auch nichts anderes als den Zeiger auch das angegebene Zeichen zu setzen, dabei aber auch jedes Zeichen zu lesen. Das macht warscheinlich auch den zeitunterschied aus. Da macht also das stringbefüllen auch nich mehr viel aus.

Kurzer Test bei 3MB-File:

mit readln :
-------------
skippen dauerte, Sec : 0.0 //ist in dem Fall übersprungen worden
parsen dauerte, Sec : 0.43


mit skip:
---------
skippen dauerte, Sec : 0.4
parsen dauerte, Sec : 0.0


Also : eine richtige Zeitersparniss hat man da nicht. Für die StringOBJ-Erstellung braucht er lediglich 0,03 Sec mehr und das ist ja nicht die Menge.

;-)
 
Such mal nach RandomAccessFile: RandomAccessFile

Da hast Du eine Methode length() und eine Methode seek(long pos). Sobald Du an der richtigen Position bist, kannst Du über readInt() etc. Deine Daten lesen.
 
Hoi,

der Tip war echt gut. Im èbrigen sollte ja die methode seek(long pos) den Zeiger in diesem File auf die gewünschte Stelle packen. Also wie "skip()"(im BeispielOben) das tun sollte. Der grosse unterschied dabei ist nur dass im myRAF-Fall es so flott geht dass man die Zeit schon fast gar nicht mehr messen kann.

Also ich habs so gemacht:

RandomAccessFile myRAF=new RandomAccessFile(myFile, "rw");

myRAF.seek(myRAF.length()-20);

String readLn;

while((readLn=myRAF.readLine())!=null) {
if(readLn.indexOf("%%EOF")>-1) {
returnValue=true;
} // end if
} // end while



//////-----------

Zeitmessung sieht so aus:

skippen dauerte, Sec : 0.0
parsen dauerte, Sec : 0.0

super nicht ;-) Danke nochmal
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben