Ausgabe
Ich habe eine .txt-Datei, auf die viele Benutzer zugreifen werden, möglicherweise gleichzeitig (oder in der Nähe davon), und deshalb brauche ich eine Möglichkeit, diese txt-Datei zu ändern, ohne eine temporäre Datei zu erstellen, und ich habe keine Antwort gefunden oder Lösung dazu. Bisher habe ich nur diesen Ansatz gefunden ->
Vorhandene Datei nehmen -> etwas ändern -> in eine neue Datei schreiben (Temp-Datei) -> alte Datei löschen.
Aber sein Ansatz ist nicht gut für mich, ich brauche so etwas wie: Vorhandene Datei nehmen -> ändern -> speichern.
Ist das möglich? Es tut mir wirklich leid, wenn diese Frage bereits existiert. Ich habe versucht, Stack-Overflow zu durchsuchen, und ich habe Oracle Docs gelesen, aber ich habe keine Lösung gefunden, die meinen Anforderungen entspricht.
BEARBEITEN:
Nach der Änderung würde die Datei dieselbe Größe wie zuvor behalten. Stellen Sie sich zum Beispiel eine Liste von Studenten vor, jeder Student kann den Wert 1 oder 0 haben (die Prüfung bestanden oder nicht bestanden)
In diesem Fall müsste ich also nur ein Zeichen pro Zeile in einer Datei aktualisieren (dh pro Schüler). Beispiel:
Lee Jackson 0 -> Lee Jackson 0
Bob White 0 -> würde -> Bob White 1 werden
Jessica Woo 1 -> Jessica Woo 1
Im obigen Beispiel haben wir eine Datei mit 3 Datensätzen untereinander und ich muss den 2. Datensatz aktualisieren, während der 1. und 3. gleich werden würden, und das alles, ohne eine neue Datei zu erstellen.
Lösung
Hier ist ein möglicher Ansatz mit RandomAccessFile
. Die Idee wäre, readline
es in Strings zu lesen, sich aber die Position in der Datei zu merken, damit Sie dorthin zurückkehren und eine neue Zeile schreiben können. Es ist immer noch riskant, falls irgendetwas in der Textcodierung die Bytelänge ändern würde, da dies beispielsweise den Zeilenumbruch überschreiben könnte.
void modifyFile(String file) throws IOException {
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
long beforeLine = raf.getFilePointer();
String line;
while ((line = raf.readLine()) != null) {
// edit the line while keeping its length identical
if (line.endsWith("0")) {
line = line.substring(0, line.length() - 1) + "1";
}
// go back to the beginning of the line
raf.seek(beforeLine);
// overwrite the bytes of that line
raf.write(line.getBytes());
// advance past the line break
String ignored = raf.readLine();
// and remember that position again
beforeLine = raf.getFilePointer();
}
}
}
Der Umgang mit der korrekten String-Codierung ist in diesem Fall schwierig. Wenn sich die Datei nicht in der von readline()
und verwendeten Codierung befindet getBytes()
, können Sie dies umgehen, indem Sie dies tun
// file is in "iso-1234" encoding which is made up.
// reinterpret the byte as the correct encoding first
line = new String(line.getBytes("ISO-8859-1"), "iso-1234");
... modify line
// when writing use the expected encoding
raf.write(line.getBytes("iso-1234"));
Siehe So lesen Sie eine UTF8-codierte Datei mit RandomAccessFile?
Beantwortet von – zapl
Antwort geprüft von – David Marino (FixError Volunteer)