How to Read and Write Byte Streams

Businessman working at desk

Jetta Productions / Getty Images

Reading and writing binary streams is one of the most common I/O tasks a Java application can perform. It can be performed by looking at each individual byte in a stream or by using a more structured buffered approach.

Note: This article looks at reading binary data from a

example.jpg
file. If you try this code then simply replace the name of the
example.jpg
with the path and name of a jpeg file on your computer.

Byte by Byte

The

java.io
class was the first Java api to provide Input/Output functionality. It has two methods that can be used to input and output byte streams (blocks of 8 bits) from and to a file. These classes are the
FileInputStream
and
FileOutputStream
. These methods provide a basic method of I/O by allowing a file to be input or output one byte at a time. In practice it's better to use a buffered method for binary streams but it's good to look at the most basic building block of the Java I/O functionality.

Notice how we place the I/O handling inside a

try, catch, finally
block—this is to make sure we handle IO exceptions and to properly close the streams. The catch block will show any I/O exceptions that occur and print a message for the user. In the finally block it's important to close the streams explicitly by calling the close method otherwise they will remain open and a waste of resources. There is a check to see if the
FileInputStream
and
FileOutputStream
are null before attempting to close. This is because an I/O error could occur before the streams are initialized. For example, if the file name is incorrect the stream will not be opened properly.In the
try
block we can add code to read in the bytes:The
read
method reads in one byte from the
FileInputStream
and the write method writes one byte to the
FileOutputStream
. When the end of the file is reached and there are no more bytes to input the value of -1 is returned.

Now that Java 7 has been released you can see the benefit of one of its new features—the try with resources block. This means that if we identify the streams to the try block at the beginning it will handle closing the stream for us. This eliminates the need for the finally block in the previous example:

The full Java code listings for the two versions of the byte reading program can be found in Binary Stream Example Code.