Ich wollte eine Datei einlesen und mittels RandomAcessFile die einzelnen Zeichen ersetzten.
Soweit geht das auch, aber die Schleife ist eine Endlosschleife. Wie schreibe ich die Schleife um, dass sie nur ans Ende der Datei läuft?
Grüße
Java:
schreiben =newRandomAccessFile(datei,"rw");for(int c;( c = in.read())!=-1;){
schreiben.writeBytes("d");}
grundsätzlich liefert die methode read() einen integer Wert wieder, der das aktuelle Zeichen liefert, ist kein Zeichen mehr vorhanden, wird "-1" zurückgegeben...
Java:
while(schreiben.read()!=-1){//mache was auch immer}
Hab ich, aber jetzt überschreibt er sie nicht mehr, sondern sie ist komplett leer.
Java:
BufferedReader in =newBufferedReader(newFileReader(datei));BufferedWriter out =newBufferedWriter(newFileWriter(datei));while(in.read()!=-1){
out.write("a");}
Das geht mit Java gar nicht, sogar mit C wirds da schwierig, weil das Dateisystem die Dateien nie direkt überschreiben lässt, sondern Copys anlegt, damit die Datei zb zu einem früheren Zeitpunkt wiederhergestellt werden kann.
Gleichzeitig eine Datei auslesen und in die Datei schreiben wird wohl etwas schwierig ;-)
Warum soll die Datei überhaupt eingelesen werden, wenn sowie irgendetwas anderes reingeschrieben wird?
Das geht mit Java gar nicht, sogar mit C wirds da schwierig, weil das Dateisystem die Dateien nie direkt überschreiben lässt, sondern Copys anlegt, damit die Datei zb zu einem früheren Zeitpunkt wiederhergestellt werden kann.
Das kommt auf das Dateisystem an. Ich denke, es gibt Dateisysteme, die das so machen, aber mir möchte da spontan keines einfallen. Auf jeden Fall ist der Ansatz mit einem RandomAccessFile sehr viel besser als mit einem OutputStream, weil bei Letzterem praktisch immer neue Blöcke belegt werden, während das bei RandomAccessFile nicht unbedingt der Fall sein muss.
Ach, ja, da fällt mir ein: Man sollte, wenn man fertig mit Schreiben (oder Lesen) einer Datei ist, diese auch schließen (also den Datenstrom schließen). Dazu gibt es gerade [c]close()[/c]. Gepufferte Datenströme à la BufferedOutputStream führen dabei auch ein [c]flush()[/c] aus (zumindest in aktuellen Java-Versionen).
Je nach Datei- und/oder Betriebssystem kann das Vergessen des Schließens Probleme verursachen, z.B., dass andere Prozesse auf die Datei nicht zugreifen können, bis das Java-Programm beendet ist, oder (trotz [c]flush()[/c]!) einfach nichts in der Datei steht, obwohl gerade in sie geschrieben wurde (auch eine Möglichkeit, Datenverlust zu provozieren). Vielleicht ist das Betriebssystem auch der Meinung, dass ein Prozess nur eine ganz bestimmte Maximalzahl an Dateien gleichzeitig geöffnet haben darf, und so wird es plötzlich unmöglich, z.B. nach 255 vergessenen [c]close()[/c] eine weitere Datei zu öffnen!? Wer weiß …
closen (wenn man das so sagen kann^^) tue ich, wenn man das bei dem ausschnitt auch nicht sieht
Auf jeden Fall ist der Ansatz mit einem RandomAccessFile sehr viel besser als mit einem OutputStream, weil bei Letzterem praktisch immer neue Blöcke belegt werden, während das bei RandomAccessFile nicht unbedingt der Fall sein muss.
Tja, das ist so eine Sache. Die einzige Möglichkeit der Pufferung (mal abgesehen von Kunstgriffen à la [c]FileChannel.map()[/c], der mir aber angesichts des schwach spezifizierten Verhaltens in dieser Situation eher unangebracht erscheint) ist dort die Verwendung von [c]write(byte[])[/c] bzw. [c]write(byte[], int, int)[/c]: Ein byte-Array mit Zufallszahlen vorbereiten und dann dieses rausschreiben, neu mit Zufallszahlen belegen, rausschreiben usw., bis mindestens einmal die komplette Datei überschrieben ist. Als Größe für das Array empfehle ich 8192 Bytes, das ist zumindest die Standardgröße des Puffers eines [c]BufferedOutputStream[/c] und damit hatte ich bisher nur gute Erfahrungen, was Performance angeht. Ob damit aber auch Zugriffe wie hier über ein [c]RandomAccessFile[/c] vergleichbar schnell möglich sind, kann ich nicht sagen.
Du solltest aber aufpassen, wenn es dir darum gehen sollte, die Datei mehrmals zu überschreiben: Wenn du Pech hast, puffert das Betriebssystem (oder die JVM) die Änderungen, bevor sie tatsächlich auf die Platte geschrieben werden. So könnte dann ein mehrfaches Überschreiben tatsächlich nur ein mehrfaches Überschreiben im Arbeitsspeicher, aber nur ein einfaches Überschreiben auf der Platte bedeuten. Welche write-Methode du benutzt, ist dabei unerheblich.