dataoutputstream默认使用大端字节序,writedouble按ieee 754标准写入64位双精度浮点数,writeutf先写2字节大端长度再写修改版utf-8编码,读取必须配套使用datainputstream的readdouble和readutf。

DataOutputStream 默认使用大端字节序(Big-Endian),这正是 IEEE 754 双精度浮点数和 UTF-8 字符串的标准网络字节序,所以你不需要额外处理字节序 —— writeDouble 和 writeUTF 本身就是按标准字节顺序写入的。
writeDouble 按 IEEE 754 大端格式写入
它把 double 值按 64 位 IEEE 754 标准转换为字节,并以大端(最高有效字节在前)方式写入。这是 Java 规范强制要求的,也是跨平台解析 double 的通用格式。
- 例如:writeDouble(3.141592653589793) → 写入 8 个字节:0x400921FB54442D18(十六进制,大端)
- 该结果可被 C/C++、Python struct.unpack('>d', ...) 或任何遵循 IEEE 754 + Big-Endian 的程序正确读取
writeUTF 按修改版 UTF-8 编码写入
它不是直接写原始 UTF-8 字节,而是先写入 2 字节长度(大端),再写入对应字符串的修改版 UTF-8 编码(与标准 UTF-8 几乎一致,但仅对 \u0000–\u007F 和 \u0080–\u07FF 区间做了兼容处理;\u0800–\uFFFF 编码方式与标准 UTF-8 相同)。
- 长度字段是 unsigned short(0–65535),所以最多支持 65535 个 UTF-16 代码单元(不是字符数,含代理对)
- 例如:"你好" → 长度 2(两个 char),接着写入 0xE4BFA0 0xE5A5BD(UTF-8 字节序列,大端长度 + 连续字节)
- 注意:不能用 writeUTF 存储超过 65535 个 char 的字符串,否则抛出 UTFDataFormatException
配套读取必须用 DataInputStream
要保证正确还原,读取端必须用 DataInputStream 的 readDouble() 和 readUTF() —— 它们严格按相同规则解析:
- readDouble() 从 8 字节中按大端组装 long,再通过 Double.longBitsToDouble 转换
- readUTF() 先读 2 字节长度,再读对应字节数,最后按修改版 UTF-8 解码为 String
- 不要用 FileInputStream + 自己 decode UTF-8,否则会跳过长度字段或解码失败
如果需要纯标准 UTF-8(无长度头)或自定义字节序
DataOutputStream 不提供开关切换字节序或绕过 writeUTF 的头部。如需更灵活控制:
- 写 double:用 ByteBuffer.allocate(8).putDouble(value).order(ByteOrder.BIG_ENDIAN).array(),再用 OutputStream.write(byte[])
- 写 UTF-8:用 string.getBytes(StandardCharsets.UTF_8),先写长度(如 int 四字节大端),再写字节数组
- 这样可与其他语言(如 Go、Rust)或二进制协议(Protocol Buffers)更好互操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











