DataInputStream and DataOutputStream

Naveen AnamaneniUpdated · 4 min read
mediumJava 25javaiobinary

DataOutputStream and DataInputStream are wrapper streams used to write and read Java primitive values, such as int, double and boolean, and strings, in a compact binary form. A text file stores the number 1234567 as seven characters; a data stream stores it as exactly 4 bytes. The format is the same on every computer, so a file written on one machine can be read on another. In this lesson, you will learn the methods of data streams and the most important rule: values must be read back in exactly the order and types they were written.

Methods

DataOutputStreamDataInputStreamSize
writeBoolean(b)readBoolean()1 byte
writeByte(b)readByte()1 byte
writeShort(s)readShort()2 bytes
writeChar(c)readChar()2 bytes
writeInt(i)readInt()4 bytes
writeLong(l)readLong()8 bytes
writeFloat(f)readFloat()4 bytes
writeDouble(d)readDouble()8 bytes
writeUTF(s)readUTF()2-byte length + encoded text

Reading past the end of the data throws EOFException.

Example: Saving and Loading Student Records

Let's see an example that saves three records in binary form and loads them back.

DataDemo.java▶ Try it
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
 
public class DataDemo {
    public static void main(String[] args) throws IOException {
        try (DataOutputStream out = new DataOutputStream(
                new BufferedOutputStream(
                    new FileOutputStream("students.dat")))) {
            out.writeUTF("Navika");
            out.writeInt(91);
            out.writeDouble(9.1);
            out.writeUTF("Srihitha");
            out.writeInt(78);
            out.writeDouble(7.8);
        }
        System.out.println("File size: " + Files.size(Path.of("students.dat")));
 
        try (DataInputStream in = new DataInputStream(
                new BufferedInputStream(new FileInputStream("students.dat")))) {
            while (true) {
                String name = in.readUTF();
                int marks = in.readInt();
                double gpa = in.readDouble();
                System.out.println(name + " " + marks + " " + gpa);
            }
        } catch (EOFException e) {
            System.out.println("End of file");
        }
    }
}
Output
File size: 42
Navika 91 9.1
Srihitha 78 7.8
End of file

Explanation: Each record is written as a string, an int and a double. "Navika" takes 2 + 6 bytes, the int 4 and the double 8, which is 20 bytes; Srihitha's record is 22 bytes, for 42 in all. The reader reads the same types in the same order, and stops when readUTF hits the end of the file and throws EOFException.

Example: Reading in the Wrong Order

WrongOrder.java▶ Try it
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
 
public class WrongOrder {
    public static void main(String[] args) throws IOException {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        try (DataOutputStream out = new DataOutputStream(bytes)) {
            out.writeInt(91);
            out.writeInt(78);
        }
        try (DataInputStream in = new DataInputStream(
                new ByteArrayInputStream(bytes.toByteArray()))) {
            System.out.println("As one long: " + in.readLong());
        }
    }
}
Output
As one long: 390842024014

Explanation: Two int values (8 bytes) were written, but they were read back as one long (also 8 bytes). Nothing complained, and the result is a meaningless number: 91 x 2^32 + 78. Data streams can't detect such mistakes.

Common Mistakes

Reading with different types or order than writing. You get garbage, not an error.

Using writeChars and expecting readUTF to read it. Use writeUTF with readUTF.

Looping forever without catching EOFException. Either store a count first, or catch the exception.

Practice

  1. Easy: Write the numbers 1 to 10 as int values to a file, then read them back and print their sum.
  2. Harder: Save a list of products (name, price, quantity) by first writing the number of products with writeInt, then reading exactly that many records back.

Quick check: Data streams

4 questions
1How many bytes does writeInt write?
2Which pair handles strings?
3What happens if you read in a different order than you wrote?
4What signals the end of the data?

Key Takeaways

Was this tutorial helpful?

Lesson 347 of 482