In an earlier article, we looked at reading and writing different types of files in Java. In this short article, you will learn how to read and write binary files in Java.
Reading Binary Files
The following example demonstrates how you can use the FileInputStream
class to read a binary file, one byte at a time without any buffering:
try {
// create a reader
FileInputStream fis = new FileInputStream(new File("input.dat"));
// read one byte at a time
int ch;
while ((ch = fis.read()) != -1) {
System.out.print((char) ch);
}
// close the reader
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
If you are reading a large file, the above program may take some time to complete as it reads only one byte at a time.
For better I/O performance, you should use the BufferedInputStream
class as it reads a set of bytes all at once into an internal byte array buffer, reducing the number of calls to the disk, hence increasing I/O performance. By default, the internal buffer size is 8KB but we can specify a custom buffer size at the time of initialization.
Here is an example that uses BufferedInputStream
with default buffer size to read a binary file:
try {
// create a reader
FileInputStream fis = new FileInputStream(new File("input.dat"));
BufferedInputStream reader = new BufferedInputStream(fis);
// read one byte at a time
int ch;
while ((ch = reader.read()) != -1) {
System.out.print((char) ch);
}
// close the reader
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
And we can specify a custom internal buffer size like below:
// custom buffer size
int BUFFER_SIZE = 16 * 1024; // 16KB
// create a reader
FileInputStream fis = new FileInputStream(new File("input.dat"));
BufferedInputStream reader = new BufferedInputStream(fis, BUFFER_SIZE);
If your binary file has encoding other the default character encoding of the operating system, or you want to explicitly set an encoding scheme, you have to use the InputStreamReader
class instead:
try {
// create a reader
FileInputStream fis = new FileInputStream(new File("input.dat"));
// specify UTF_16 characer encoding
InputStreamReader reader = new InputStreamReader(fis, StandardCharsets.UTF_16);
// read one byte at a time
int ch;
while ((ch = reader.read()) != -1) {
System.out.print((char) ch);
}
// close the reader
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
Writing Binary Files
The following example shows how you can use the FileOutputStream
class to write data to a binary file in Java:
try {
// create a writer
FileOutputStream fos = new FileOutputStream(new File("output.dat"));
// write data to file
fos.write("Hey, there!".getBytes());
fos.write("\n".getBytes());
fos.write("How are you doing?".getBytes());
// close the writer
fos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
The above example works perfect but every time the write()
method is called, an I/O operation to the disk is performed. It may not be a desirable solution for writing large-sized files.
To reduce the number of I/O operations and improve performance, you should use the BufferedOutputStream
class instead. Just like BufferedInputStream
, it uses an internal buffer of size 8KB (can be customized) to store the data and only writes to the disk when the buffer is full.
Here is an example that uses BufferedOutputStream
with default buffer size to write data to a binary file:
try {
// create a writer
FileOutputStream fos = new FileOutputStream(new File("output.dat"));
BufferedOutputStream writer = new BufferedOutputStream(fos);
// write data to file
writer.write("Hey, there!".getBytes());
writer.write("\n".getBytes());
writer.write("How are you doing?".getBytes());
// flush remaining bytes
writer.flush();
// close the writer
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
Notice the writer.flush()
method call in the above code. You must call this method before closing the BufferedOutputStream
instance to make sure that the remaining data in the internal buffer is flushed to the disk.
You can also specify a custom internal buffer size like below:
// custom buffer size
int BUFFER_SIZE = 16 * 1024; // 16KB
// create a writer
FileOutputStream fos = new FileOutputStream(new File("output.dat"));
BufferedOutputStream writer = new BufferedOutputStream(fos, BUFFER_SIZE);
If you are writing a binary file with an encoding other than the default character encoding of the operating system or if you want to write non-ASCII characters, you should the OutputStreamWriter
class as shown below:
try {
// create a writer
FileOutputStream fos = new FileOutputStream(new File("output.dat"));
// set encoding to UTF_8
OutputStreamWriter writer = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
// write data to file
writer.write("Hey, there!");
writer.write("\n");
writer.write("How are you doing?");
// flush remaining bytes
writer.flush();
// close the writer
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
You can even wrap the OutputStreamWriter
object in a BufferedWriter
object to improve the performance by reducing the number of I/O operations performed:
try {
// create a writer
FileOutputStream fos = new FileOutputStream(new File("output.dat"));
// set encoding to UTF_8
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
// wrap in `BufferedWriter`
BufferedWriter writer = new BufferedWriter(osw);
// write data to file
writer.write("Hey, there!");
writer.newLine();
writer.write("How are you doing?");
// flush remaining bytes
writer.flush();
// close the writer
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
For more file read and write examples, check out the Reading and Writing Files in Java tutorial.
✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.