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 @attacomsian on Twitter. You can also follow me on LinkedIn and DEV. Subscribe to RSS Feed.

👋 If you enjoy reading my articles and want to support me to continue creating free tutorials, ☕ Buy me a coffee (cost $5).