Java DataInputStream

The Java DataInputStream class, java.io.DataInputStream, enables you to read
Java primitives (int, float, long etc.) from an InputStream instead of only raw bytes.
You wrap an InputStream in a DataInputStream and then you can read Java primitives via ‘
the DataInputStream. That is why it is called DataInputStream – because it reads data (numbers)
instead of just bytes.

Java DataInputStream converts bytes to int, long, float and double from an InputStream

The DataInputStream is handy if the data you need to read consists of Java primitives larger than one byte each, like
int, long, float, double etc. The DataInputStream expects the multi byte primitives to be written
in network byte order (Big Endian – most significant byte first).

Often you will use a Java DataInputStream to read data written by a
Java DataOutputStream.

The Java DataInputStream class is a subclass of InputStream, so DataInputStream also has the basic read methods
that enable you to read a single byte or an array of bytes from the underlying InputStream, in case you need that.
In this Java DataInputStream tutorial I will only cover the extra methods the DataInputStream has, though.

One issue to keep in mind when reading primitive data types is, that there is no way to distinguish a valid
int value of -1 from the normal end-of-stream marker. That basically means, that you cannot see from the primitive
value returned if you have reached end-of-stream. Therefore you kind of have to know ahead of time what data types
to read, and in what sequence. In other words, you need to know ahead of time what data you can read from the
DataInputStream.

Java DataInputStream Example

Here is a Java DataInputStream example:

DataInputStream dataInputStream = new DataInputStream(
                            new FileInputStream("binary.data"));

int    aByte   = input.read();
int    anInt   = input.readInt();
float  aFloat  = input.readFloat();
double aDouble = input.readDouble();
//etc.

input.close();

First a DataInputStream is created with a FileInputStream as source for its data.
Second, Java primitives are read from the DataInputStream.

Create a DataInputStream

You create a Java DataInputStream via its constructor. When you do so, you pass an InputStream as parameter
from which the primitive data types are to be read. Here is an example of creating a
Java DataInputStream:

DataInputStream dataInputStream =
        new DataInputStream(
                new FileInputStream("data/data.bin"));

Using a DataInputStream With a DataOutputStream

As mentioned earlier, the DataInputStream class is often used together with a DataOutputStream.
Therefore I just want to show you an example of first writing data with a DataOutputStream and
then reading it again with a DataInputStream. Here is the example Java code:

import java.io.*;


public class DataInputStreamExample {

    public static void main(String[] args) throws IOException {
        DataOutputStream dataOutputStream =
                new DataOutputStream(
                        new FileOutputStream("data/data.bin"));

        dataOutputStream.writeInt(123);
        dataOutputStream.writeFloat(123.45F);
        dataOutputStream.writeLong(789);

        dataOutputStream.close();

        DataInputStream dataInputStream =
                new DataInputStream(
                        new FileInputStream("data/data.bin"));

        int   int123     = dataInputStream.readInt();
        float float12345 = dataInputStream.readFloat();
        long  long789    = dataInputStream.readLong();

        dataInputStream.close();

        System.out.println("int123     = " + int123);
        System.out.println("float12345 = " + float12345);
        System.out.println("long789    = " + long789);
    }
}

This example first creates a DataOutputStream and then writes an int, float
and a long value to a file. Second the example creates a DataInputStream which reads
the int, float and long value in from the same file.

Read boolean

You can read a Java boolean from the DataInputStream using its readBoolean() method.
Here is an example of reading a boolean from a Java DataInputStream using readBoolean():

boolean myBoolean = dataInputStream.readBoolean();

Read byte

You can read a Java byte from the DataInputStream using its readByte() method.
Here is an example of reading a byte from a Java DataInputStream using readByte():

byte myByte = dataInputStream.readByte();

Read Unsigned byte

You can read a Java unsigned byte (only positive values) from the DataInputStream using its readUnsignedByte() method.
The unsigned byte is returned as an int because byte values above 127 cannot fit into the signed byte data type.
Here is an example of reading an unsigned byte from a Java DataInputStream using readUnsignedByte():

int myUnsignedByte = dataInputStream.readUnsignedByte();

Read char

You can read a Java char from the DataInputStream using its readChar() method.
Here is an example of reading a char from a Java DataInputStream using readChar():

char myChar = dataInputStream.readChar();

Read double

You can read a Java double from the DataInputStream using its readDouble() method.
Here is an example of reading a double from a Java DataInputStream using readDouble():

double myDouble = dataInputStream.readDouble();

Read float

You can read a Java float from the DataInputStream using its readFloat() method.
Here is an example of reading a float from a Java DataInputStream using readFloat():

float myFloat = dataInputStream.readFloat();

Read short

You can read a Java short from the DataInputStream using its readShort() method.
Here is an example of reading a short from a Java DataInputStream using readShort():

short myShort = dataInputStream.readShort();

Read Unsigned short

You can read a Java unsigned short (only positive values) from the DataInputStream using its readUnsignedShort() method.
The unsigned short is returned as an int because short values above 32767 cannot fit into the signed short data type.
Here is an example of reading an unsigned short from a Java DataInputStream using readUnsignedShort():

int myUnsignedShort = dataInputStream.readUnsignedShort();

Read int

You can read a Java int from the DataInputStream using its readInt() method.
Here is an example of reading an int from a Java DataInputStream using readInt():

int   myInt = dataInputStream.readInt();

Read long

You can read a Java long from the DataInputStream using its readLong() method.
Here is an example of reading an int from a Java DataInputStream using readLong():

long   myLong = dataInputStream.readLong();

Read UTF

You can read a Java String from the DataInputStream using its readUTF() method.
The data is expected to be encoded in UTF-8 to be readable by this method.
Here is an example of reading a String from a Java DataInputStream using readUTF():

String   myString = dataInputStream.readUTF();

Closing a DataInputStream

When you are finished reading data from the DataInputStream you should remember to close it.
Closing a DataInputStream will also close the InputStream instance from which the
DataInputStream is reading.

Closing a DataInputStream is done by calling its close() method. Here is how
closing a DataInputStream looks:

dataInputStream.close();

You can also use the try-with-resources construct
introduced in Java 7. Here is how to use and close a DataInputStream looks with the try-with-resources
construct:

InputStream input = new FileInputStream("data/data.bin");

try(DataInputStream dataInputStream =
    new DataInputStream(input)){

    int data = dataInputStream.readInt();

    int   int123     = dataInputStream.readInt();
    float float12345 = dataInputStream.readFloat();
    long  long789    = dataInputStream.readLong();
}

Notice how there is no longer any explicit close() method call. The try-with-resources construct
takes care of that.

Notice also that the first FileInputStream instance is not created inside
the try-with-resources block. That means that the try-with-resources block will not automatically close this
FileInputStream instance. However, when the DataInputStream is closed
it will also close the InputStream instance it reads from, so the FileInputStream
instance will get closed when the DataInputStream is closed.