Java: Save/Write String Into a File

Introduction

Saving a String into files can be done in a few ways using Java. In this article, we'll show some common methods for writing a String into a file.

Here's a list of all the classes and methods we'll go over:

Files.writeString()

Since Java 11, the Files class contains a useful utility method Files.writeString(). This method comes in two variants. The most basic form requires a Path of the file to write to and the textual contents. The other variant also accepts an optional CharSet:

Path path = Paths.get("output.txt");
String contents = "Hello";

try {
    Files.writeString(path, contents, StandardCharsets.UTF_8);
} catch (IOException ex) {
	// Handle exception
}

There is little room for flexibility here, but it works great if you need to write something down into a file quickly.

Files.write()

A String, like other objects, can be converted into a byte[]. The Files.write() method deals with bytes:

Path path = Paths.get("output.txt");
String someString = "Hello World";
byte[] bytes = someString.getBytes();

try {
    Files.write(path, bytes);
} catch (IOException ex) {
	// Handle exception
}

There is no need to close any resources since we haven't opened any resources ourselves.

FileWriter

FileWriter is one of the simplest ways to write some textual contents into a file. We'll create a File instance and pass it into the FileWriter constructor to "bridge" them.

Then, we simply use the FileWriter instance to write to it:

File output = new File("output.txt");
FileWriter writer = new FileWriter(output);

writer.write("This text was written with a FileWriter");
writer.flush();
writer.close();

After using the writer, it's important to flush and close the resources. Alternatively, you can do this with the try-with-resources syntax:

try(FileWriter writer = new FileWriter("output.txt")) {
    writer.write("This text was written with a FileWriter"); 
}
catch(IOException e){
    // Handle the exception
}

BufferedWriter

BufferedWriter is a wrapper object that is used around objects of type Writer. If we have an existing Writer such as FileWriter, we can wrap it inside a BuffereWriter.

BufferedWriter is best used when there are multiple write() operations for a file. In this case, those multiple writes are temporarily stored into an internal buffer and written into a file only when there is enough content. This avoids having to store each new chunk of text into a file and instead provides an appropriate buffer for temporary storage.

Using a BufferedWriter is much more efficient than FileWriter for multiple writes, but it doesn't help with a single write.

In fact, using BufferedWriter for a single write would cause unnecessary overhead. For such simple cases, FileWriter is a much better option.

Let's create a BufferedWriter:

BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));

BufferedWriter and FileWriter both extend Writer so they have the same methods:

try(BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
    writer.write("Written with BufferedWriter);
}
catch(IOException e){
    // Handle the exception
}

PrintWriter

PrintWriter lets us format the text before writing it down. It contains methods we're used to, such as printf(), println(), etc. Let's create a PrintWriter:

File output = new File("output.txt");
PrintWriter writer = new PrintWriter(output);

A better way to work with a PrintWriter is with the try-with-resources syntax:

try(PrintWriter writer = new PrintWriter(new FileWriter("output.txt"))) {
    // Write using the PrintWriter instance
} catch {
    // Handle Exception
}

Once we have a PrintWriter instance, let's explore some of the methods it provides.

PrintWriter with append()

PrintWriter, like the StringBuilder provides the append() method which allows us to append contents to the end of an existing file.

Let's appent() some text to an empty writer:

writer.append("Welcome to my fruit store! From me, you can buy:\n");
writer.append("Apples");
writer.append("\n");
writer.append("Oranges");
writer.append("\n");
writer.append("Bananas");

The append() method returns the PrintWriter object it was called upon. This makes it possible to chain append() methods and organize them more neatly:

writer.append("Welcome to my fruit store! From me, you can buy:\n");
writer.append("Apples\n").append("Oranges\n").append("Bananas\n");

PrintWriter with print()

PrintWriter contains methods for formatted printing. These include print(), printf(), and println():

writer.print("Welcome to my fruit store %f", 2.0);
writer.printf("From me, you can buy %s and %s.", "apples", "oranges");

PrintWriter with write()

With write(), we can write many different types of textual contents into the stream. Examples include char arrays, Strings, and integers:

char[] hello = {'H', 'e', 'l', 'l', 'o', '!', '\n'};

writer.write(hello);
writer.write("Welcome to my fruit store\n");
writer.write("From me, you can buy apples and oranges");

The write() method only accepts content without formatting options so it's similar to print(), but can't format Strings.

To finalize each PrintWriter "session" of either appending, printing, or writing, it's important to flush and close the stream:

writer.flush();
writer.close();

The flush() method "flushes" the contents into the file and close() permanently closes the stream.

Note: If you use the try-with-resources syntax, it'll flush and close the stream automatically.

Conclusion

In this article, we've shown some common methods for writing strings into files. There are many options because there are many possible use-cases.

We've covered the Files.writeString(), Files.write() methods, as well as the FileWriter, BufferedWriter and PrintWriter classes.

Author image
About Luka Čupić
Croatia Website