datainputstream和dataoutputstream必须成对使用、读写顺序严格一致、包装底层字节流,支持自动类型转换与大端序解析,用于安全读写java基本数据类型和utf-8字符串。

要用 DataInputStream 和 DataOutputStream 读写 Java 基本数据类型,关键在于“成对使用 + 顺序一致 + 包装底层流”。它们不直接操作文件或网络,而是作为装饰器,包装已打开的字节流(如 FileInputStream / FileOutputStream),提供类型安全、平台无关的二进制读写能力。
必须用对应的流配对,且写入顺序决定读取顺序
DataInputStream 只能可靠读取由 DataOutputStream 写出的数据。两者共享统一的大端序(Big-Endian)和编码规则(如 readUTF() 对应 writeUTF())。一旦顺序错乱,比如先 readInt() 再 readBoolean(),但实际文件里是 boolean 在前,就会导致字节偏移、数值错乱,甚至抛出 EOFException 或 IOException。
- 写入示例(DataOutputStream):
dos.writeBoolean(true);
dos.writeInt(12345);
dos.writeDouble(3.14159);
dos.writeUTF("hello");
- 对应读取(DataInputStream)必须严格一致:
boolean b = dis.readBoolean();
int i = dis.readInt();
double d = dis.readDouble();
String s = dis.readUTF();
正确创建和关闭流:推荐 try-with-resources
不能直接 new DataInputStream(),必须传入一个已打开的 InputStream;同理,DataOutputStream 必须包装 OutputStream。资源必须显式关闭,否则可能造成句柄泄漏。使用 try-with-resources 最安全简洁:
- 写文件:
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) {
dos.writeInt(100);
dos.writeDouble(2.718);
} catch (IOException e) { e.printStackTrace(); }
- 读文件:
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) {
int x = dis.readInt();
double y = dis.readDouble();
} catch (IOException e) { e.printStackTrace(); }
支持的基本类型与特殊处理
每个基本类型都有专属方法,底层自动按固定字节数和大端序解析:
- readBoolean():读 1 字节(0x00 → false,0x01 → true)
- readByte() / readUnsignedByte():读 1 字节(有符号/无符号 int)
- readShort() / readUnsignedShort():读 2 字节,高位在前
- readChar():读 2 字节,按 UTF-16BE 解码为 char
- readInt() / readLong() / readFloat() / readDouble():分别读 4/8/4/8 字节,IEEE 754 格式
- readUTF():先读 2 字节长度(short),再按修改版 UTF-8 读取内容(支持中文,但长度上限 65535 字节)
常见误区与注意事项
这些细节容易被忽略,却直接影响程序健壮性:
- 不要用 DataInputStream 读普通文本文件或非 DataOutputStream 写出的二进制文件——格式不匹配会立即失败
- readUTF() 不能读 writeBytes() 或 writeChars() 写出的内容;后者需手动循环 readByte()/readChar() 并自行拼接
- 大数据量场景下,可在外层套一层 BufferedInputStream / BufferedOutputStream 提升性能
- 遇到流末尾时,多数 readXxx() 抛 EOFException(继承自 IOException),应在 catch 块中统一处理
- writeUTF() 对超长字符串(>65535 字节)会抛 UTFDataFormatException,需提前校验
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











