Zeichen ersetzen mit RandomAccesFile

Aloisia

Mitglied
Hallo, ich habe eine Datei, die aus mehreren Zeilen besteht in denen jeweils eine Zahl (0-9) steht.

Code:
0
2
0
4
6
7
5

nun möchte ich in eine während der Laufzeit bestimme Zeile (zum Bsp. Zeile 4) springen und dort die Zahl mit einer anderen ersetzen. (Also zum Beispiel die 4 mit einer 7.)
Java:
  try {
       RandomAccessFile file = new RandomAccessFile("zeichen.txt","rw");
       file.seek(8);
       file.write("7".getBytes());
       file.close();
     } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }

Irgendwie funktioniert das Ganze aber nicht so ganz, es werden Ausgaben erzeugt wie:

Code:
0
2
0
74
6
7
5
 
Hi

bei Textdateien sind RandomAccessFiles etc. unbrauchbar.
Die allgemeingültige Lösung ist, die ganze Datei neu zu schreiben,
also Zeile für Zeile einlesen...(und Zeilen mitzählen, um an der
passenden Stelle statt der alten die neue Zeile hin zu schreiben)
 
Moin,

warum "seek(8)" ?? Sollte es nicht der Wert "4" sein ?

Mit "Write" schreibst Du an die Position des aktuellen FilePointers! Überschrieben wird dadurch nichts!
Du müsstest also den alten Wert erst konkret löschen ...

Gruß
Klaus
 
Hi

bei Textdateien sind RandomAccessFiles etc. unbrauchbar.
Die allgemeingültige Lösung ist, die ganze Datei neu zu schreiben,
also Zeile für Zeile einlesen...(und Zeilen mitzählen, um an der
passenden Stelle statt der alten die neue Zeile hin zu schreiben)

Aha. Könnte aber bei einer Datei mit 200Mio Zeilen etwas aufwändig werden.
Gibt es keine andere Lösung um 1 Zeichen zu ersetzen?

Moin,

warum "seek(8)" ?? Sollte es nicht der Wert "4" sein ?

Mit "Write" schreibst Du an die Position des aktuellen FilePointers! Überschrieben wird dadurch nichts!
Du müsstest also den alten Wert erst konkret löschen ...

Gruß
Klaus

Nach ein paar Probeversuchen habe ich "festgestellt", dass
0 der Dateianfang ist, also das erste Zeichen (logisch...) - schreibe ich auf Pos 0, dann ersetze ich das erste Zeichen.
1 ist in meinem Fall anscheinend der erste Zeilenumbruch,
2 ist in meinem Fall der Anfang der zweiten Zeile,
3 ist der zweite Zeilenumbruch...

meine Methode hat in ein paar Versuchen funktioniert, und dann wieder nicht,... daher dachte ich ich mache irgendeinen Fehler.
 
Moin,

Nach ein paar Probeversuchen habe ich "festgestellt", dass
0 der Dateianfang ist, also das erste Zeichen (logisch...) - schreibe ich auf Pos 0, dann ersetze ich das erste Zeichen.
1 ist in meinem Fall anscheinend der erste Zeilenumbruch,
2 ist in meinem Fall der Anfang der zweiten Zeile,
3 ist der zweite Zeilenumbruch...
meine Methode hat in ein paar Versuchen funktioniert, und dann wieder nicht,... daher dachte ich ich mache irgendeinen Fehler
ja klar, wenn Du Zeilenumbrüche drin hast, zählt das wie ein Zeichen!

Und sheel hat natürlich mit seinem Argument recht .... aber gerade bei 200 Mio. Zeilen (??? ich dachte nur ein paar Zeichen, so wie dein Beispiel) wird es mit dem RandomAccessFile wohl unmöglich .....

Gruß
Klaus
 
Moin,


ja klar, wenn Du Zeilenumbrüche drin hast, zählt das wie ein Zeichen!

Das witzige daran ist: nicht immer... manchmal schreibt er dann wirklich davor bzw. danach....
Und sheel hat natürlich mit seinem Argument recht .... aber gerade bei 200 Mio. Zeilen (??? ich dachte nur ein paar Zeichen, so wie dein Beispiel) wird es mit dem RandomAccessFile wohl unmöglich .....

Gruß
Klaus

mein Beispiel sollte nur verdeutlichen, was ich meine. Wären das 100 Zeilen, dann würde ich eine Liste erstellen, die Werte einlesen, und die Datei damit neu erstellen (bis auf den einen geänderten Wert).

Wenn jetzt aber jedes Mal eine Liste erstellt wird, eingelesen wird,.... und dann wieder geschrieben wird, habe ich ja ca. 400Mio Operationen die "unnötig" sind... und das bei jedem Änderungsvorgang.

Ich habe schon das Internet abgesucht, man findet auch viele "Beispiele" die "zeigen" was RandomAccessFile kann, allerdings steht nur in der Beschreibung, dass man damit Zeichen ersetzen kann... Das "Beispiel" sieht dann eher nach Javadoc von RAF aus.
 
Moin,


gar nicht witzig ;-)
kommt drauf, wie deine Zeilenumbrüche ausschauen: nur ein Zeichen oder doch zwei (\r oder \r\n) !!

Gruß
Klaus

schon witzig. Ich kopiere die Datei, so wie sie ist.
Lasse das Testprogramm (nur der obige code) drüberlaufen und es ersetzt, ich lösche die Datei, füge die kopierte wieder dort ein, lasse das Programm noch einmal drüberlaufen und erhalte ein anderes Ergebnis.
 
kommt drauf, wie deine Zeilenumbrüche ausschauen: nur ein Zeichen oder doch zwei (\r oder \r\n) !!
Genau, zum Beispiel deswegen meine Aussage mit "unbrauchbar"
Zeichensätze (Unicode, verschiedene Bytelängen pro Zeichen) sind das nächste Übel, usw.usw.

Warum speichert man 200Mio. Datensätze in irgendeine Textdatei?
Datenbanken...

edit:
Wenn es wirklich immer nur eine Ziffer ist:
Vergiss die Zeilenwechsel und stell sicher das überall reiner ASCII in Verwendung ist
(kein getBytes auf Java-Strings natürlich auch), dann gehts relativ problemlos
 
Zuletzt bearbeitet:
Genau, zum Beispiel deswegen meine Aussage mit "unbrauchbar"
Zeichensätze (Unicode, verschiedene Bytelängen pro Zeichen) sind das nächste Übel, usw.usw.

Warum speichert man 200Mio. Datensätze in irgendeine Textdatei?
Datenbanken...

edit:
Wenn es wirklich immer nur eine Ziffer ist:
Vergiss die Zeilenwechsel und stell sicher das überall reiner ASCII in Verwendung ist
(kein getBytes auf Java-Strings natürlich auch), dann gehts relativ problemlos

Ich dachte das geht einfacher... Ich lese die Zeilen auch an anderer Stelle mit BufferedReader aus, und da ist

Java:
Integer.parseInt(br.readline());

ziemlich einfach gewesen...


Ich bin aber auch offen, das "Design" nochmal zu ändern. Wie würdet ihr das angehen?
 
Zurück