How to append text to an existing file in Java?
Solution 1
Are you doing this for logging purposes? If so there are several libraries for this. Two of the most popular are Log4j and Logback.
Java 7+
For a one-time task, the Files class makes this easy:
try {
Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
Careful: The above approach will throw a NoSuchFileException
if the file does not already exist. It also does not append a newline automatically (which you often want when appending to a text file). Another approach is to pass both CREATE
and APPEND
options, which will create the file first if it doesn't already exist:
private void write(final String s) throws IOException {
Files.writeString(
Path.of(System.getProperty("java.io.tmpdir"), "filename.txt"),
s + System.lineSeparator(),
CREATE, APPEND
);
}
However, if you will be writing to the same file many times, the above snippets must open and close the file on the disk many times, which is a slow operation. In this case, a BufferedWriter
is faster:
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
}
Notes:
- The second parameter to the
FileWriter
constructor will tell it to append to the file, rather than writing a new file. (If the file does not exist, it will be created.) - Using a
BufferedWriter
is recommended for an expensive writer (such asFileWriter
). - Using a
PrintWriter
gives you access toprintln
syntax that you're probably used to fromSystem.out
. - But the
BufferedWriter
andPrintWriter
wrappers are not strictly necessary.
Older 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
}
Exception Handling
If you need robust exception handling for older Java, it gets very verbose:
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
}
}
Solution 2
You can use fileWriter
with a flag set to true
, for appending.
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());
}
Solution 3
Shouldn't all of the answers here with try/catch blocks have the .close() pieces contained in a finally block?
Example for marked answer:
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();
}
}
Also, as of Java 7, you can use a try-with-resources statement. No finally block is required for closing the declared resource(s) because it is handled automatically, and is also less verbose:
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)))) {
out.println("the text");
} catch (IOException e) {
System.err.println(e);
}
Solution 4
Using Apache Commons 2.1:
FileUtils.writeStringToFile(file, "String to append", true);
Solution 5
Slightly expanding on Kip's answer, here is a simple Java 7+ method to append a new line to a file, creating it if it doesn't already exist:
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...
}
Further notes:
-
The above uses the
Files.write
overload that writes lines of text to a file (i.e. similar to aprintln
command). To just write text to the end (i.e. similar to aprint
command), an alternativeFiles.write
overload can be used, passing in a byte array (e.g."mytext".getBytes(StandardCharsets.UTF_8)
). -
The
CREATE
option will only work if the specified directory already exists - if it doesn't, aNoSuchFileException
is thrown. If required, the following code could be added after settingpath
to create the directory structure:Path pathParent = path.getParent(); if (!Files.exists(pathParent)) { Files.createDirectories(pathParent); }
flyingfromchina
Updated on January 16, 2021Comments
-
flyingfromchina over 3 years
I need to append text repeatedly to an existing file in Java. How do I do that?
-
Alphaaa almost 11 yearsOh, thank you. I was amused by the complexity of all other answers. I really do not get why people like to complicate their (developer) life.
-
Kip over 10 yearsWhen
out
goes out of scope, it is automatically closed when it gets garbage-collected, right? In your example with thefinally
block, I think you actually need another nested try/catch aroundout.close()
if I remember correctly. The Java 7 solution is pretty slick! (I haven't been doing any Java dev since Java 6, so I was unfamiliar with that change.) -
Svetlin Zarev over 10 yearsYou should either use java7 try-with-resources or put the close() in a finally block, in order to make sure that the file is closed in case of exception
-
Svetlin Zarev over 10 yearsLets imagine that
new BufferedWriter(...)
throws an exception; Will theFileWriter
be closed ? I guess that it will not be closed, because theclose()
method (in normal conditions) will be invoked on theout
object, which int this case will not be initialized - so actually theclose()
method will not be invoked -> the file will be opened, but will not be closed. So IMHO thetry
statement should look like thistry(FileWriter fw = new FileWriter("myFile.txt")){ Print writer = new ....//code goes here }
And he shouldflush()
the writer before exiting thetry
block!!! -
Navin almost 10 years@Kip Nope, going out-of-scope does nothing in Java. The file will get closed at some random time in the future. (probably when the program closes)
-
Emily L. over 9 yearsCaution, the "Older java" example will not properly close the stream if an exception is thrown inside the try block.
-
Mahdi over 9 yearsit's not work for me. in destination file, there is one "test" and many empty space
-
xehpuk about 9 yearsThis is horrible advice. You open a stream to the file 42 times instead of once.
-
dantuch about 9 years@xehpuk well, it depends. 42 is still ok, if it makes code much more readable. 42k wouldn't be acceptable.
-
Pshemo about 9 years
close
should be placed infinally
block just like shown in @etech's answer in case exception would be thrown between creation of FileWriter and invoking close. -
Chetan Bhasin about 9 yearsWhat are the imports required? Which library do these things use?
-
assylias almost 9 yearsIf you use Java 7+, then why not use a simple
Files.write
instead of a PrintWriter of a BufferedWriter of a FileWriter? -
Vadzim almost 9 yearsThis answer fails to correctly handle exceptions. See @Emily's answer for proper way.
-
Vadzim almost 9 years+1 for correct ARM with Java 7. Here is good question about this tricky theme: stackoverflow.com/questions/12552863/….
-
yongtw123 almost 9 yearsa caveat: when using BufferedWriter
write(String string)
if one expects a new line after each string written,newLine()
should be called -
Henry Zhu almost 9 yearsGood answer, although its better to use System.getProperty( "line.separator" ) for a new line rather than "\n".
-
RadijatoR almost 9 yearsWhy is FileWriter treated like expensive writer?
-
Kip almost 9 years@RadijatoR Because it has to do disk I/O operations. In the JavaDoc for BufferedWriter, it says "In general, a Writer sends its output immediately to the underlying character or byte stream. Unless prompt output is required, it is advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as FileWriters and OutputStreamWriters"
-
Buffalo almost 9 yearsThe problem with this approach is that it opens and closes the output stream every single time. Depending on what and how often you write to your file, this could result in a ridiculous overhead.
-
Rahbee Alvee almost 9 yearsThis can be done in one line of code. Hope this helps :) Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND);
-
Evgeni Sergeev over 8 yearsThe
File
and filename-based constructors ofPrintWriter
mention that they buffer automatically. But when aPrintWriter
wraps anotherWriter
, there is no comment in the docs on whether it adds another layer of buffering or not. Given the ambiguity, it seems best to include aBufferedWriter
explicitly, as in this answer. -
Evgeni Sergeev over 8 yearsHmm, for some reason
PrintWriter.close()
is not declared asthrows IOException
in the docs. Looking at its source, theclose()
method, indeed, cannot throwIOException
, because it catches it from the underlying stream, and sets a flag. So if you're working on the code for the next Space Shuttle or an X-ray dose metering system, you should usePrintWriter.checkError()
after attempting toout.close()
. This should really have been documented. -
syfantid about 8 years@etech Will the second approach need the
flush
method? -
Decoded about 8 yearsThanks Emily L. I've edited the answer to reflect that good catch!
-
Kip about 8 years@Decoded your suggested edit was a syntax error.
out
is only defined in thetry
block. In thefinally
block it does not exist. You would have to move the declaration ofout
out of thetry
block. This is exactly the problem that the Java 7+ syntax resolves. As I've noted, I've left exception handling for the reader; I think it's beyond the scope of this answer. -
Kip about 8 years@Decoded I've rolled back your edit on this answer, as it does not compile.
-
Kip about 8 yearsIf we're going to be super paranoid about closing, each of those
XX.close()
should be in its own try/catch, right? For example,out.close()
could throw an exception, in which casebw.close()
andfw.close()
would never get called, andfw
is the one that is most critical to close. -
WestCoastProjects over 7 yearsumm ... what?? This will overwrite the file.
-
Decoded over 7 years@Kip, What was the issue? I must have entered a "typo".
-
Kip over 7 years@Decoded you had
fw.close()
in a finally block, without a nested try/catch (.close()
can throwIOException
) -
php_coder_3809625 over 7 yearsHow bout try-with-resources?
try(FileWriter fw = new FileWriter(filename,true)){ // Whatever }catch(IOException ex){ ex.printStackTrace(); }
-
Bhaskara Arani over 7 yearswhat is obj.toJSONString() here?
-
Gherbi Hicham over 7 years@BhaskaraArani It's just a string, he put an example of a JSON object converted to a string but the idea is that it could be any string.
-
i000174 over 7 yearsYou should close only the out variable! stackoverflow.com/questions/484925/…
-
MartyIX over 7 years
-
David Charles about 7 yearsThe above is just a quick example implementation of the solution presented At this link. So you can copy and and run the code and immediately see how it works, be sure that the output.out file is in the same directory as the Writer.java file
-
Konstantin K about 7 years@Buffalo is right. But you can always use StringBuilder for building large chunks (that are worth writing) before writing them to file.
-
Steve Chambers almost 7 yearsA couple of possible "gotchas" with the Java 7 method: (1) If the file doesn't already exist,
StandardOpenOption.APPEND
won't create it - kind of like a silent failure as it won't throw an exception either. (2) Using.getBytes()
will mean there is no return character before or after the appended text. Have added an alternative answer to address these. -
Kip almost 7 years@SteveChambers Thanks for the input. I couldn't believe that append mode does not create the file if it does not exist, so I had to try it to confirm. Not sure what they were thinking there... I found that it does actually throw an exception, but if you copy/paste my code and leave the
catch
block blank, then you don't see it. I've updated my answer to reflect these issues and I added a link to your answer. -
Michael almost 7 yearsIs it safe to use the faster, buffered operations? I'm trying to log something that happens right before a crash, and I need to make sure the file is going to get written.
-
Kip almost 7 years@Michael when the buffered writer is closed, it will write whatever is in the buffer. Or you can explicitly call
flush()
to force it to flush its buffer (writing the contents) immediately. -
evg345 over 6 yearsits may be not enough:) better version is Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND, StandardOpenOption.CREATE);
-
Andrew Koster over 5 years"If you need robust exception handling for older Java, it gets very verbose." If by "verbose" you mean "a horrifying abomination".
-
Enigmatic over 5 yearsDo you need to check if the file exists? I thought
.CREATE
does the job for you. -
Janac Meena about 5 yearsThis works in Scala as well: try { Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND) } catch { case ioe: IOException => { println("IOException thrown!") } case e: Exception => println("Non-IOException thrown!") }
-
Rafael Membrives almost 4 years@KonstantinK but then all the content you need to write is loaded into memory.
-
Steve Chambers over 3 yearsIf
.CREATE
is used when the file already exists it silently fails to append anything - no exception is thrown but the existing file contents remain unchanged. -
lapo over 3 yearsUsing
APPEND
+CREATE
works perfectly, no check necessary:Files.write(Paths.get("test.log"), (Instant.now().toString() + "\r\n").getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
-
Weekend about 2 yearsThe
Files.writeString()
andPath.of()
are both no symbol error, is it a typo? -
Kip about 2 years@Weekend it worked when i wrote the answer but i haven't done any serious java development in quite a long time 🤷