2008-11-04 8 views
24

Ich habe derzeit 2 BufferedReader s in der gleichen Textdatei initialisiert. Wenn ich fertig bin, die Textdatei mit dem ersten BufferedReader zu lesen, benutze ich den zweiten, um einen weiteren Durchgang durch die Datei von oben zu machen. Mehrere Durchgänge durch die gleiche Datei sind notwendig.Java BufferedReader zurück an den Anfang einer Textdatei?

Ich weiß über reset(), aber es muss mit dem Aufruf mark() vorangestellt werden und mark() muss wissen, die Größe der Datei, etwas, ich glaube nicht, dass ich mich kümmern sollte.

Ideen? Pakete? Libs? Code?

Dank TJ

Antwort

24

Was ist der Nachteil der gerade einen neuen BufferedReader von oben lesen zu schaffen? Ich würde erwarten, dass das Betriebssystem die Datei zwischenspeichert, wenn sie klein genug ist.

Wenn Sie sich Sorgen um die Leistung machen, haben Sie bewiesen, dass dies ein Flaschenhals ist? Ich würde einfach die einfachste Sache machen und sich nicht darum kümmern, bis du einen bestimmten Grund dafür hast. Ich meine, du könntest das ganze Ding einfach in Erinnerung behalten und dann die zwei Durchgänge auf dem Ergebnis machen, aber wieder wird das komplizierter sein als nur von Anfang an mit einem neuen Leser zu lesen.

27

Die gepufferten Leser sollen eine Datei sequentiell lesen. Was Sie suchen, ist die java.io.RandomAccessFile, und dann können Sie seek() verwenden, um Sie an die gewünschte Stelle in der Datei zu bringen.

try{ 
    String fileName = "c:/myraffile.txt"; 
    File file = new File(fileName); 
    RandomAccessFile raf = new RandomAccessFile(file, "rw"); 
    raf.readChar(); 
    raf.seek(0); 
} catch (FileNotFoundException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Der "rw" ist ein Modus, der Zeichen detailed here ist:

der Direktzugriffsleser ist wie so umgesetzt.

Der Grund, warum die Leser mit sequentiellem Zugriff so eingerichtet sind, ist, dass sie ihre Puffer implementieren können und dass Dinge nicht unter ihren Füßen geändert werden können. Zum Beispiel sollte der Dateileser, der dem gepufferten Leser gegeben wird, nur von diesem gepufferten Leser betrieben werden. Wenn es einen anderen Ort gab, der die Datei beeinflussen könnte, könnte dies zu einem inkonsistenten Vorgang führen, da ein Leser seine Position im Datei-Leseprogramm fortsetzte, während der andere dieselbe beibehalten wollte, da Sie jetzt den anderen Reader verwenden.

3

Der beste Weg, um fortzufahren ist, Ihren Algorithmus so zu ändern, dass Sie den zweiten Durchgang NICHT benötigen. Ich habe diesen Ansatz ein paar Mal benutzt, als ich mich mit riesigen (aber nicht schrecklichen, d. H. Wenigen GBs) Dateien befassen musste, die nicht in den verfügbaren Speicher passten.

Es könnte schwierig sein, aber die Performance-Gewinn in der Regel lohnt sich der Aufwand

+0

Könnten Sie näher ausführen? Ich habe eine Datei, die 30 MB groß ist, ich kann nicht alles in den Speicher laden. Ich habe die Daten sortiert und möchte nun eine binäre Suche direkt in der Datei durchführen. Dafür muss ich zufällig suchen. –

+0

Heutzutage nehme ich an, du meinst 30GB, es sei denn, du verwendest wirklich kleine eingebettete hw (aber dann wäre es plattenlos) Wie auch immer, Zufallssuche auf Festplatten ruiniert oft vollständig die logarithmische Leistung der binären Suche. Ein paar Alternativen sind 1) sequentieller Zugriff (ja, auf der Festplatte ist eine sequentielle Suche möglicherweise schneller als eine binäre Suche) oder 2) ein gemischter Ansatz wie die Verwendung von B-Baum http://en.wikipedia.org/wiki/ B-Baum Wenn diese Hinweise nicht genug sind, möchten Sie vielleicht Ihre Frage als separate statt als Kommentar stellen (bitte, posten Sie hier einen Kommentar mit einem Link zu der Frage, um mich zu pingen) – Davide

-1

„Die ganze Geschichte über Zeichen() und reset() in BufferedReader der schlechten Design schmatzt.“

Warum erweitern Sie diese Klasse nicht und lassen Sie sie eine Mark() im Konstruktor() ausführen und dann eine seek (0) in topOfFile() -Methode.

BR,
~ A

1

über die Marke/Reset:

Die Markierung Methode in BufferedReader nimmt einen readAheadLimit Parameter, die begrenzt, wie weit man nach einer Markierung lesen kann, bevor Reset unmöglich wird.Zurücksetzen bedeutet nicht wirklich ein Dateisystem-Suchlauf (0), es sucht nur innerhalb des Puffers. Um den Javadoc zu zitieren:

readAheadLimit - Begrenzung der Anzahl der Zeichen, die gelesen werden können, während die Markierung erhalten bleibt. Nach dem Lesen dieser vielen Zeichen kann der Versuch, den Stream zurückzusetzen, fehlschlagen. Ein Grenzwert, der größer als die Größe des Eingabepuffers ist, bewirkt, dass ein neuer Puffer zugewiesen wird, dessen Größe nicht kleiner als der Grenzwert ist. Daher sollten große Werte mit Vorsicht verwendet werden.

Verwandte Themen