DataInputStream and DataOutputStream
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
| DataOutputStream | DataInputStream | Size |
|---|---|---|
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.
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");
}
}
}File size: 42
Navika 91 9.1
Srihitha 78 7.8
End of fileExplanation: 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
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());
}
}
}As one long: 390842024014Explanation: 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
- Easy: Write the numbers 1 to 10 as
intvalues to a file, then read them back and print their sum. - 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.
Key Takeaways
Was this tutorial helpful?