Ersetzen von text in einer Datei mit dem Stream - Java 8
Bin ich zu schreiben versucht, eine API zu ersetzen Sie alle Zeilen mit einem bestimmten Teilstring mit einem anderen string in ein text-Datei.
Ich bin mit Java 8 stream zu filtern, welche Linien enthält, die einem bestimmten Muster. Ich habe problem mit der Datei schreiben Teil.
Files.lines(targetFile).filter(line -> line.contains(plainTextPattern)).parallel()
.map(line-> line.replaceAll(plainTextPattern, replaceWith)).parallel();
Obige code liest die Datei Zeile für klug, filtert die Zeilen, die mit dem Suchmuster und ersetzt Sie mit der geben Sie die Zeichenfolge und gibt wieder einen stream von strings, die nur die Linien ersetzt.
Müssen wir schreiben diese Zeilen wieder in die Datei. Da verlieren wir den stream, sobald die pipeline endet, ich angehängt, die folgenden in der pipeline:
.forEach(line -> {
try {
Files.write(targetFile, line.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
}
Ich hatte gehofft, es würde das schreiben in die Datei werden nur die geänderten (denn es ist in der pipeline) - Linie und lassen Sie die anderen Zeilen unverändert.
Aber es scheint truncate die Datei für jede Zeile in der Datei, und behalten Sie nur die zuletzt bearbeiteten Zeile und löscht alle Zeilen, die keine Entsprechung in der pipeline.
Gibt es etwas, das mir fehlt zur Bedienung von Dateien mit streams?
- Aus Dokumentation: "standardmäßig die Methode erstellt eine neue Datei oder überschreibt eine vorhandene Datei.". Für die Lösung gelesen rest der Dokumentation. Denken Sie auch daran, Sie können nicht einfach ändern, der alte text-Datei. Müssen Sie erstellen eine neue mit den richtigen änderungen und ersetzen Sie es.
- Danke! Ich dachte, der Verwendung von StandardOpenOption.APPEND. Aber ich spürte, dass es nicht sinnvoll ist, weil ich nicht wollen, es zu bekommen, angehängt an das Ende der Datei. Es hat zum ersetzen der vorhandenen Linie. Übersehe ich wieder etwas?
- Ich habe nur versucht, anfügen. Es fügt alle Inhalte (einschließlich der Zeilen, die nicht übereinstimmen) zum Ende der Datei.. zumindest das sagt mir die unvergleichlichen Linien sind nicht völlig verloren. Aber ich brauche, um herauszufinden, wie zu schreiben, die Datei mit dem neuen Inhalt.
- Versuchen, nur ersetzen Sie die Zeilen der Datei, die Sie wollen-vor allem, wenn die Datei text und Zeilenumbrüche hat, statt nur den Austausch bytes -- wird ein riesiges Durcheinander, wenn es überhaupt möglich ist. Nur tun das die meisten einfach Sache: Lesen Sie die ganze Datei in Zeilen, ersetzen Sie die entsprechenden stellen, schreiben die ganze Sache wieder.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mit
filter
eliminiert alles, was nicht mit dem übereinstimmt, den filter aus dem stream. (Außerdem, für was es Wert ist, a) müssen Sie nurparallel
einmal, b)parallel
ist das nicht effektiv auf streams kommen von der I/O-Quellen, c) es ist fast nie eine gute Idee zu verwendenparallel
bis Sie haben wirklich versucht, die nicht-parallel und fand es zu langsam.)Sagte: es gibt keine Notwendigkeit heraus zu filtern und die Zeilen, die dem Muster entsprechen, wenn Sie gehen zu tun eine
replaceAll
. Ihr code sollte wie folgt Aussehen:So Leid, Ihnen zu sagen, dass dies ist nicht, wie Sie mit Dateien arbeiten. Wenn Sie wollen schreiben Sie in die Mitte der Datei, müssen Sie
RandomAccess
; Holen Sie sich eineFilePointer
", "seek", dass die Zeiger, und schreiben von dort aus.Dieser hält, wenn die Größe der Daten, die Sie möchten, schreiben ist gleich der Größe der Daten, die Sie überschreiben möchten. Wenn dies nicht der Fall ist, kopieren Sie den Schwanz der Datei in einen temporären Puffer und fügen Sie den text, den Sie schreiben wollen.
Und btw
parallelStreams
aufIO
gebundenen Aufgaben ist oft eine schlechte Idee.