DataInputStream 读取基本类型
你有没有想过:为什么 Java 的基本类型(int、long、double)可以方便地写入文件和从文件读取?
答案是 DataInputStream。
DataInputStream 和 DataOutputStream 是一对,它们以二进制格式读写 Java 基本类型,比文本格式更紧凑、更精确(不会有精度损失)。
基本用法
java
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("data.bin")))) {
int i = dis.readInt(); // 4 字节
long l = dis.readLong(); // 8 字节
double d = dis.readDouble(); // 8 字节
boolean b = dis.readBoolean(); // 1 字节
String s = dis.readUTF(); // 变长:2 字节长度 + N 字节内容
}读取方法一览
| 方法 | 返回类型 | 字节数 |
|---|---|---|
readBoolean() | boolean | 1 |
readByte() | byte | 1 |
readUnsignedByte() | int | 1 |
readChar() | char | 2 |
readShort() | short | 2 |
readUnsignedShort() | int | 2 |
readInt() | int | 4 |
readLong() | long | 8 |
readFloat() | float | 4 |
readDouble() | double | 8 |
readUTF() | String | 变长 |
readUTF() 的格式
readUTF() 读取的是 writeUTF() 写入的格式:
[2 字节长度][N 字节 UTF-8 内容]java
// 写入 "Hello"
dos.writeUTF("Hello");
// 实际写入:[00, 05, 48, 65, 6c, 6c, 6f]
// 长度 5,H e l l o
// 读取
String s = dis.readUTF();
// 读取前 2 字节得到长度 5,再读 5 字节得到内容注意:readUTF() / writeUTF() 是配套的,不能和 readChars() / writeChars() 混用。
处理文件结束
java
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("data.bin")))) {
try {
while (true) {
int id = dis.readInt();
String name = dis.readUTF();
System.out.println(id + ": " + name);
}
} catch (EOFException e) {
// 文件结束,正常退出
}
}读取字节数组
DataInputStream 没有直接的 read(byte[]) 方法,需要用 readFully():
java
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("data.bin")))) {
byte[] buf = new byte[1024];
dis.readFully(buf); // 读取恰好 1024 字节,不够就抛异常
// 读取指定字节数
dis.readFully(buf, 0, 100); // 读取前 100 字节
}读取大端序 / 小端序
DataInputStream 只支持大端序(高位字节在前)。小端序需要自己处理:
java
public static int readIntLittleEndian(DataInputStream dis)
throws IOException {
int ch1 = dis.read();
int ch2 = dis.read();
int ch3 = dis.read();
int ch4 = dis.read();
return (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | (ch1);
}配合 Buffered 使用
永远配合 BufferedInputStream 使用:
java
// ❌ 差:没有缓冲
DataInputStream dis = new DataInputStream(
new FileInputStream("data.bin"));
// ✅ 好:有缓冲
DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("data.bin")));常见错误
类型不匹配
java
// ❌ 写入 int,读取 long
dos.writeInt(42);
long value = dis.readLong(); // 读错了 8 字节而不是 4 字节
// ❌ writeUTF 和 readLine 混用
dos.writeUTF("Hello");
String s = dis.readLine(); // readLine 不适合读 writeUTF 的格式!不处理 EOF
java
// ❌ 没有处理 EOF
int value = dis.readInt(); // 读到文件末尾会抛 EOFException
// ✅ 正确处理
try {
while (true) {
int value = dis.readInt();
process(value);
}
} catch (EOFException e) {
// 文件结束
}记住这个约束:
读写顺序必须一致,写了什么类型就读什么类型。 DataInputStream 和 DataOutputStream 是一对,不能混用其他格式。
