Best Ways to Write to File in Java
For programmers writing in Java who need to do a Java write to file, there are four main ways to accomplish this: FileWriter, BufferedWriter, java 7 Files and FileOutput Stream. We’ll touch on all of those today.
Here’s a brief overview, and we’ll expand on each of these as we go along:
FileWriter
Since it’s the simplest way to write a file in Java, FileWriter is one of the most popular methods. It allows the programmer to write String to the file and write byte array, thanks to overloaded write method. FileWriter also allows for writing part of the String or byte array. Since FileWriter writes directly to files, it should be used when the number of writes are lower.
BufferedWriter
BufferedWriter has many similarities to FileWriter, with the exception of an internal buffer for writing data into File. If the actual number of write operations is greater, the IO operations will be fewer, with enhanced performance. This is what makes BufferedWriter a better choice when there’s a great number of write operations to be done.
FileOutputStream
When there’s a great deal of raw stream data to be written to file, FileOutputStream is a great choice. FileWriter and BufferedWriter are great for writing text to file, but FileOutputStream is certainly better for these applications.
Files
Java 7 was the debut of Files utility class, and its OutputStream is designed to write byte array into file.
Java Write to File Example (courtesy of journaldev.com)
Here’s an example of a standard method to write to file in java:
package com.journaldev.files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class WriteFile {
/**
* This class shows how to write file in java
* @param args
* @throws IOException
*/
public static void main(String[] args) {
String data = "I will write this String to File in Java";
int noOfLines = 10000;
writeUsingFileWriter(data);
writeUsingBufferedWriter(data, noOfLines);
writeUsingFiles(data);
writeUsingOutputStream(data);
System.out.println("DONE");
}
/**
* Use Streams when you are dealing with raw data
* @param data
*/
private static void writeUsingOutputStream(String data) {
OutputStream os = null;
try {
os = new FileOutputStream(new File("/Users/pankaj/os.txt"));
os.write(data.getBytes(), 0, data.length());
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Use Files class from Java 1.7 to write files, internally uses OutputStream
* @param data
*/
private static void writeUsingFiles(String data) {
try {
Files.write(Paths.get("/Users/pankaj/files.txt"), data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Use BufferedWriter when number of write operations are more
* It uses internal buffer to reduce real IO operations and saves time
* @param data
* @param noOfLines
*/
private static void writeUsingBufferedWriter(String data, int noOfLines) {
File file = new File("/Users/pankaj/BufferedWriter.txt");
FileWriter fr = null;
BufferedWriter br = null;
String dataWithNewLine=data+System.getProperty("line.separator");
try{
fr = new FileWriter(file);
br = new BufferedWriter(fr);
for(int i = noOfLines; i>0; i--){
br.write(dataWithNewLine);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Use FileWriter when number of write operations are less
* @param data
*/
private static void writeUsingFileWriter(String data) {
File file = new File("/Users/pankaj/FileWriter.txt");
FileWriter fr = null;
try {
fr = new FileWriter(file);
fr.write(data);
} catch (IOException e) {
e.printStackTrace();
}finally{
//close resources
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Other Approaches for Writing to File
There are actually a multitude of methods for writing to file when it comes to Java. Each has its advantages and pitfalls, and the variety of methods can make it quite confusing.
Input streams
Writing input streams is the simplest and most direct way to write data into files for Java.
Here’s an example, courtesy octoperf.com:
package com.octoperf;
import com.google.common.io.Closer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import static com.google.common.base.Charsets.UTF_8;
public class JavaWriteFileTest {
private static final String HELLO_WORLD = "Hello World!";
private static final String OUT_TXT = "out.txt";
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void inputOutputTryFinally() throws IOException {
final File file = folder.newFile(OUT_TXT);
BufferedOutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
out.write(HELLO_WORLD.getBytes(UTF_8));
} finally {
if (out != null) {
out.close();
}
}
}
@Test
public void inputOutputCloser() throws IOException {
final File file = folder.newFile(OUT_TXT);
final Closer closer = Closer.create();
try {
final BufferedOutputStream out = closer.register(new BufferedOutputStream(new FileOutputStream(file)));
out.write(HELLO_WORLD.getBytes(UTF_8));
} finally {
closer.close();
}
}
@Test
public void inputOutputTryResources() throws IOException {
final File file = folder.newFile(OUT_TXT);
try (final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
out.write(HELLO_WORLD.getBytes(UTF_8));
}
}
}
Here, we’ve used BufferedOutputStream and FileOutputStream to write the classic example of Hello World! Into the file. It’s not advisable to phrase it this way, however:
Out.write(HELLO_WORLD.getBytes() );
In a case like this, the platform default encoding converts the string into bytes, which is fine but can result in problems if there are any changes in the encoding. To convert the string into bytes, the code:
HELLO_WORLD.getBytes(UTF_8)
would come into play, but this isn’t a very elegant solution. A DataOutputStream can improve and streamline this:
@Test
public void dataOutputTryFinally() throws IOException {
final File file = folder.newFile(OUT_TXT);
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
out.writeUTF(HELLO_WORLD);
} finally {
if (out != null) {
out.close();
}
}
At this point, the code out.writeUTF(HELLO_WORLD); can be used to write the string directly in UTF-encoded bytes.
BufferedWriter
BufferedWriter buffers characters for more streamlined writing of strings, arrays and single characters, as a character-output stream. While the default is large enough for most applications, the buffer size may be specified. In most cases a Writer can send output straight to the byte stream or underlying character. In most cases, a BufferedWriter can be wrapped around any Writer in instances where Write operations can be costly, as in writing to file in Java with OutputStreamWriters or FileWriters.
Here’s an example:
@Test
public void dataOutputTryFinally() throws IOException {
final File file = folder.newFile(OUT_TXT);
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
out.writeUTF(HELLO_WORLD);
} finally {
if (out != null) {
out.close();
}
}
This illustrates three different ways to use BufferedWriter. The try…finally pattern comes into play to ensure the writer is closed, even when there’s an exception during the write. bufferedWriterCloser closes the writer with a finally clause, and bufferedWriter TryResources uses “try with resources” syntax that was developed with Java7.
The syntax will differ slightly depending on how you want to close the writer, but the result is still the same regardless. In all these instances, the original file content would be overwritten. Here’s an example of how to handle it if you just want to append the file:
@Test
public void bufferedWriterTryResourcesAppend() throws IOException {
final File file = folder.newFile(OUT_TXT);
try (final Writer writer = new BufferedWriter(new FileWriter(file, true))) {
writer.write(HELLO_WORLD);
}
}
In this example, did you notice the “true” 2nd argument added to FileWriter? It serves the same function as append=true. In the end, the written file will include the string “Hello World!”
PrintWriter
Here, we’ll explore a little bit about PrintWriter, which includes some nice features that enhance the standard BufferedWriter:
package com.octoperf;
import com.google.common.io.Closer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
public class JavaWriteFileTest {
private static final String HELLO_WORLD = "Hello World!";
private static final String OUT_TXT = "out.txt";
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void printWriterTryFinally() throws IOException {
final File file = folder.newFile(OUT_TXT);
PrintWriter writer = null;
try {
writer = new PrintWriter(new FileWriter(file));
writer.printf("Hello %s!", "John Smith");
} finally {
if (writer != null) {
writer.close();
}
}
}
@Test
public void printWriterCloser() throws IOException {
final File file = folder.newFile(OUT_TXT);
final Closer closer = Closer.create();
try {
final PrintWriter writer = closer.register(new PrintWriter(new FileWriter(file)));
writer.printf("Hello %s!", "John Smith");
} finally {
closer.close();
}
}
@Test
public void printWriterTryResources() throws IOException {
final File file = folder.newFile(OUT_TXT);
try (PrintWriter writer = new PrintWriter(new FileWriter(file))){
writer.printf("Hello %s!", "John Smith");
}
}
}
Note that we again used three closing methods and still came to the same result. To write a formatted string, writer.printf (“Hello %s!”, “John Smith”); is a convenient approach. This string will include “John Smith” in the file.
Don’t Forget When You’re Doing a Java Write to File
When reading or writing content from a file, don’t forget to close any associated resources.
Failing to close things properly means a pointer to the file will stay open, causing behaviors such as reaching open file limit or simply being unable to write a file because it’s considered already open.
Best of luck!