Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

    • Java IO概述
    • IO基础

    • 常用IO流

      • 文件流
      • 缓冲流
      • 数据流
        • 1. 核心类
        • 2. 读写顺序必须一致
        • 3. writeUTF 的特点
        • 4. 适合场景
        • 5. 和对象流的区别
        • 专家实践清单
        • Tips 快问快答
        • 6. 总结
      • 对象流与序列化
      • 打印流
      • 管道流
    • 文件与目录操作

    • Java NIO

    • 高级主题

    • 实践与性能优化

    • 面试与设计题

    • IO实践速查

  • JVM

目录

数据流

数据流用于按 Java 基本数据类型读写二进制数据。它不是写文本,而是按照固定二进制格式写入 int、long、double、boolean 等值。

# 1. 核心类

数据流包括:

  • DataInputStream
  • DataOutputStream

它们通常包装在其他字节流外面。

try (DataOutputStream output = new DataOutputStream(
        new BufferedOutputStream(new FileOutputStream("user.dat")))) {

    output.writeInt(1001);
    output.writeUTF("Alice");
    output.writeDouble(98.5);
}

读取时必须按照相同顺序读取:

try (DataInputStream input = new DataInputStream(
        new BufferedInputStream(new FileInputStream("user.dat")))) {

    int id = input.readInt();
    String name = input.readUTF();
    double score = input.readDouble();
}

# 2. 读写顺序必须一致

数据流没有字段名,也没有自描述元信息。写入顺序和读取顺序必须完全一致。

写入:

output.writeInt(1);
output.writeLong(100L);

读取:

int a = input.readInt();
long b = input.readLong();

如果读取顺序写错,后续数据都会错位。

# 3. writeUTF 的特点

writeUTF 使用一种修改版 UTF-8 格式,并在前面写入长度信息。它适合 Java 程序内部配套使用,但不适合作为跨语言通用协议。

如果需要跨语言协议,通常应该选择:

  • JSON
  • Protocol Buffers
  • Avro
  • MessagePack
  • 自定义明确字节序和长度字段的二进制协议

# 4. 适合场景

数据流适合:

  • Java 程序内部简单二进制格式。
  • 小型工具写入固定结构数据。
  • 单机临时数据文件。
  • 学习二进制协议编码思想。

不适合:

  • 长期演进的数据格式。
  • 多语言系统共享数据。
  • 需要兼容不同版本的复杂业务对象。
  • 需要可读性和可调试性的文件。

# 5. 和对象流的区别

数据流写的是基本类型和字符串,开发者自己维护字段顺序。

对象流写的是对象图,由 Java 序列化机制维护对象结构。

对比项 数据流 对象流
写入内容 基本类型、UTF 字符串 Java 对象
格式 简单二进制 Java 序列化格式
可读性 低 低
跨语言 差 很差
版本演进 需要手动设计 容易踩坑

# 专家实践清单

设计点 要求 原因
字段顺序 写入和读取完全一致 数据流没有字段名
字段类型 类型要严格匹配 读错类型会破坏后续解析
版本演进 手动设计版本号 新旧格式需要兼容
跨语言 谨慎使用 字节序和格式约定不透明

数据流协议通常长这样:

magic
version
fieldCount
field1
field2
checksum

# Tips 快问快答

Q:数据流主要处理什么数据? A:Java 基本类型和 UTF 字符串的二进制读写。

Q:DataInputStream 和 DataOutputStream 必须配套吗? A:通常要配套使用,否则读取顺序和类型很容易不匹配。

Q:数据流适合复杂对象吗? A:不适合,复杂对象应使用明确协议或序列化框架。

Q:数据流写出的文件可读性如何? A:较差,是二进制格式,不适合人工直接编辑。

Q:为什么要设计版本号? A:字段变化后需要识别格式版本,避免旧数据无法读取。

Q:数据流能跨语言吗? A:可以但不推荐,需要严格约定字节序、字段顺序和编码。

Q:它和对象流最大的区别是什么? A:数据流只写基本值,对象流写对象图和类元数据。

Q:生产中数据流常见用途是什么? A:小型内部二进制格式、教学协议示例或性能敏感但格式简单的场景。

# 6. 总结

数据流适合按固定顺序读写基本类型,本质上是一种简单的二进制编码工具。它可以帮助理解协议设计,但在大型生产系统中,通常会被更成熟的序列化框架替代。

上次更新: 2026/06/25, 14:19:18
缓冲流
对象流与序列化

← 缓冲流 对象流与序列化→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式