779 Stimmen

Wie fügt man in Java Text an eine bestehende Datei an?

Ich muss wiederholt Text an eine bestehende Datei in Java anhängen. Wie kann ich das tun?

926voto

Kip Punkte 102702

Tun Sie dies zu Protokollierungszwecken? Wenn ja, gibt es mehrere Bibliotheken für diese . Zwei der beliebtesten sind Log4j y Logback .

Java 7+

Bei einer einmaligen Aufgabe ist die Dateien Klasse macht dies leicht:

try {
    Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
    //exception handling left as an exercise for the reader
}

Vorsichtig : Der obige Ansatz führt zu einem NoSuchFileException wenn die Datei nicht bereits existiert. Es wird auch nicht automatisch ein Zeilenumbruch angehängt (was beim Anhängen an eine Textdatei oft gewünscht wird). Ein anderer Ansatz ist die Übergabe beider CREATE y APPEND Optionen, die die Datei zuerst erstellen, wenn sie noch nicht existiert:

private void write(final String s) throws IOException {
    Files.writeString(
        Path.of(System.getProperty("java.io.tmpdir"), "filename.txt"),
        s + System.lineSeparator(),
        CREATE, APPEND
    );
}

Wenn Sie jedoch viele Male in dieselbe Datei schreiben, müssen die obigen Schnipsel die Datei auf der Festplatte viele Male öffnen und schließen, was ein langsamer Vorgang ist. In diesem Fall sollte ein BufferedWriter ist schneller:

try(FileWriter fw = new FileWriter("myfile.txt", true);
    BufferedWriter bw = new BufferedWriter(fw);
    PrintWriter out = new PrintWriter(bw))
{
    out.println("the text");
    //more code
    out.println("more text");
    //more code
} catch (IOException e) {
    //exception handling left as an exercise for the reader
}

Notas:

  • Der zweite Parameter der FileWriter Konstruktor, dass an die Datei angehängt werden soll, anstatt eine neue Datei zu schreiben. (Existiert die Datei nicht, wird sie erstellt.)
  • Mit einer BufferedWriter wird für einen teuren Schriftsteller empfohlen (z. B. FileWriter ).
  • Mit einer PrintWriter gibt Ihnen Zugang zu println Syntax, die Sie wahrscheinlich von System.out .
  • Aber die BufferedWriter y PrintWriter Umhüllungen sind nicht unbedingt erforderlich.

Ältere Java

try {
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("myfile.txt", true)));
    out.println("the text");
    out.close();
} catch (IOException e) {
    //exception handling left as an exercise for the reader
}

Behandlung von Ausnahmen

Wenn Sie eine robuste Ausnahmebehandlung für älteres Java benötigen, wird es sehr langatmig:

FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
    fw = new FileWriter("myfile.txt", true);
    bw = new BufferedWriter(fw);
    out = new PrintWriter(bw);
    out.println("the text");
    out.close();
} catch (IOException e) {
    //exception handling left as an exercise for the reader
}
finally {
    try {
        if(out != null)
            out.close();
    } catch (IOException e) {
        //exception handling left as an exercise for the reader
    }
    try {
        if(bw != null)
            bw.close();
    } catch (IOException e) {
        //exception handling left as an exercise for the reader
    }
    try {
        if(fw != null)
            fw.close();
    } catch (IOException e) {
        //exception handling left as an exercise for the reader
    }
}

35 Stimmen

Sie sollten entweder java7 try-with-resources verwenden oder close() in einen finally-Block setzen, um sicherzustellen, dass die Datei im Falle einer Ausnahme geschlossen wird

3 Stimmen

Stellen wir uns vor, dass new BufferedWriter(...) löst eine Ausnahme aus; wird die FileWriter geschlossen werden? Ich vermute, dass sie nicht geschlossen werden wird, weil die close() Methode wird (unter normalen Bedingungen) auf der out Objekt, das in diesem Fall nicht initialisiert wird - so dass eigentlich die close() Methode wird nicht aufgerufen -> die Datei wird geöffnet, aber nicht geschlossen. Daher ist IMHO die try Anweisung sollte wie folgt aussehen try(FileWriter fw = new FileWriter("myFile.txt")){ Print writer = new ....//code goes here } Und er sollte flush() der Schreiber vor dem Verlassen des try blockieren!!!

7 Stimmen

Achtung, das "Older java"-Beispiel schließt den Stream nicht ordnungsgemäß, wenn innerhalb des try-Blocks eine Ausnahme ausgelöst wird.

202voto

northpole Punkte 10036

Sie können verwenden fileWriter mit einem Flag, das auf true zum Anhängen.

try
{
    String filename= "MyFile.txt";
    FileWriter fw = new FileWriter(filename,true); //the true will append the new data
    fw.write("add a line\n");//appends the string to the file
    fw.close();
}
catch(IOException ioe)
{
    System.err.println("IOException: " + ioe.getMessage());
}

10 Stimmen

close sollte in finally Block genau wie in @etech's Antwort für den Fall, dass zwischen der Erstellung des FileWriters und dem Aufruf von close eine Ausnahme ausgelöst wird.

5 Stimmen

Gute Antwort, obwohl es besser ist, System.getProperty( "line.separator" ) für eine neue Zeile zu verwenden, anstatt " \n ".

0 Stimmen

@Decoded Ich habe Ihre Bearbeitung dieser Antwort rückgängig gemacht, da sie nicht kompilierbar ist.

75voto

etech Punkte 2023

Sollten nicht alle Antworten hier mit try/catch-Blöcken die .close()-Teile in einem finally-Block enthalten?

Beispiel für eine markierte Antwort:

PrintWriter out = null;
try {
    out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)));
    out.println("the text");
} catch (IOException e) {
    System.err.println(e);
} finally {
    if (out != null) {
        out.close();
    }
} 

Außerdem können Sie ab Java 7 eine Versuch-mit-Ressourcen-Anweisung . Für das Schließen der deklarierten Ressource(n) ist kein finally-Block erforderlich, da dies automatisch geschieht und auch weniger umfangreich ist:

try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)))) {
    out.println("the text");
} catch (IOException e) {
    System.err.println(e);
}

1 Stimmen

Wenn out aus dem Anwendungsbereich herausgeht, wird es automatisch geschlossen, wenn es als Müll gesammelt wird, richtig? In Ihrem Beispiel mit dem finally Block, denke ich, dass Sie eigentlich ein weiteres verschachteltes Try/Catch brauchen, um out.close() wenn ich mich richtig erinnere. Die Java 7-Lösung ist ziemlich raffiniert! (Ich habe keine Java-Entwicklung seit Java 6 getan, so war ich nicht vertraut mit dieser Änderung).

2 Stimmen

@Kip Nein, das Verlassen des Geltungsbereichs bewirkt in Java nichts. Die Datei wird zu einem beliebigen Zeitpunkt in der Zukunft geschlossen. (wahrscheinlich wenn das Programm geschlossen wird)

0 Stimmen

@etech Braucht der zweite Ansatz die flush Methode?

53voto

ripper234 Punkte 211096

Verwendung von Apache Commons 2.1:

FileUtils.writeStringToFile(file, "String to append", true);

7 Stimmen

Ich danke Ihnen. Ich war amüsiert über die Komplexität aller anderen Antworten. Ich verstehe wirklich nicht, warum die Leute ihr (Entwickler-)Leben so kompliziert machen.

8 Stimmen

Das Problem bei diesem Ansatz ist, dass der Ausgabestrom jedes Mal geöffnet und geschlossen wird. Je nachdem, was und wie oft Sie in Ihre Datei schreiben, kann dies zu einem lächerlichen Overhead führen.

1 Stimmen

@Buffalo hat Recht. Aber Sie können immer StringBuilder verwenden, um große Stücke (die es wert sind, geschrieben zu werden) zu erstellen, bevor sie in eine Datei geschrieben werden.

37voto

Steve Chambers Punkte 33674

Leicht erweitert auf Kip's Antwort , Hier ist eine einfache Java 7+ Methode zum Anhängen einer neue Linie in eine Datei, Erstellung, wenn sie noch nicht vorhanden ist :

try {
    final Path path = Paths.get("path/to/filename.txt");
    Files.write(path, Arrays.asList("New line to append"), StandardCharsets.UTF_8,
        Files.exists(path) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE);
} catch (final IOException ioe) {
    // Add your own exception handling...
}

Weitere Hinweise:

  1. Die obige Darstellung verwendet die Files.write Überlast, die schreibt Zeilen von Text in eine Datei (d.h. ähnlich wie bei einer println Befehl). Um nur Text an das Ende zu schreiben (d.h. ähnlich wie bei einem print Befehl), eine Alternative Files.write Überladung kann verwendet werden, indem ein Byte-Array übergeben wird (z.B. "mytext".getBytes(StandardCharsets.UTF_8) ).

  2. Le site CREATE funktioniert nur, wenn das angegebene Verzeichnis bereits existiert - ist dies nicht der Fall, wird ein NoSuchFileException geworfen wird. Falls erforderlich, könnte der folgende Code nach der Einstellung hinzugefügt werden path um die Verzeichnisstruktur zu erstellen:

    Path pathParent = path.getParent();
    if (!Files.exists(pathParent)) {
        Files.createDirectories(pathParent);
    }

1 Stimmen

Müssen Sie prüfen, ob die Datei existiert? Ich dachte .CREATE erledigt diese Aufgabe für Sie.

0 Stimmen

Si .CREATE verwendet wird, wenn die Datei bereits existiert, wird nichts angehängt - es wird keine Ausnahme ausgelöst, aber der Inhalt der bestehenden Datei bleibt unverändert.

1 Stimmen

Verwendung von APPEND + CREATE funktioniert einwandfrei, keine Überprüfung erforderlich: Files.write(Paths.get("test.log"), (Instant.now().toString() + "\r\n").getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X