# How to Read and Write Binary Files in Java

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Dec 5, 2019. Topics: Java.
Canonical URL: https://attacomsian.com/blog/java-read-write-binary-files

> A quick article to learn how to read and write binary files in Java.

In an [earlier article](https://attacomsian.com/blog/java-read-write-files), 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:

```java
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:
 
```java
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:

```java
// 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:

```java
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:

```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:

```java
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:

```java
// 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:

```java
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:

```java
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](https://attacomsian.com/blog/java-read-write-files) tutorial.
