从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java 数据类型

    • Java 多版本配置
    • 面向对象

    • Java 核心类

    • IO

      • IO 介绍
        • 什么是 IO
        • 什么是流
        • Java 中的 IO 流
        • 同步和异步
        • 小结
      • File 对象介绍
      • InputStream
      • OutputStream
      • Decorator 模式
      • 读写 zip 文件
      • Properties 类
      • 读取 classpath 中的配置文件
      • 序列化与反序列化
      • Reader
      • Writer
      • PrintStream 和 PrintWriter
      • Scanner
      • 使用 Files
      • Console
      • IO 系列小结
    • Java 与时间

    • 异常处理

    • 哈希和加密算法

    • Java8 新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • IO
2023-02-02
目录

IO 介绍

# IO 介绍

简单介绍下 IO 的概念和 Java 中 IO 的体系。

# 什么是 IO

在冯诺依曼结构中,IO 是重要的组成部分,几乎所有编程语言都涉及 IO。IO 是指 Input/Output,即输入和输出,这里的输入和输出都是以内存(存储器)为中心的:

冯诺依曼结构

  • CPU 只处理内存中的数据,因此如果要处理不在内存中的数据,要先将数据输入(Input)到内存,例如将文件加载到内存,或者读取网络上的数据(例如数据库)到内存。
  • 内存是易失性的,关机或者宕机后,数据就没有了。所以如果要保存内存中的数据,就得将数据输出(Output)到文件里,或者输出到网络接口(例如数据库)。

我们的 Java 程序也是在内存中由 CPU 运行的,内存中的数据无非就是 0 和 1,这里的 0 和 1 可能是字符数据,也可能是二进制数据,可以用 Java 的 byte[],String 来表示并处理。

# 什么是流

在程序中,我们经常需要读取文件,那么如何读取比较好呢?比如一个大文件,不可能瞬间就能读取到内存里,读取速度取决于硬件的性能;并且内存里也不一定有足够的内存放下整个文件。

因此,一个文件的数据,我们都是一部分一部分地读取的。这种读取方式,我们称为流,数据就像水流一样一点一点地流入到内存里;输出也是一样的,向水流一样流出到硬盘上,因此我们也可以称这种读取方式为 IO 流,IO 流是一种顺序读写数据的模式。

字节是计算机存储单元的基本单位,因此 IO 流也可以称为字节流,例如我们读取一个 6 字节大小的文件,相当于读入了 6 个字节的数据:

╔════════════╗
║   Memory   ║
╚════════════╝
       ▲
       │0x48
       │0x65
       │0x6c
       │0x6c
       │0x6f
       │0x21
 ╔═══════════╗
 ║ Hard Disk ║
 ╚═══════════╝
1
2
3
4
5
6
7
8
9
10
11
12
13

我们按顺序读取这 6 个字节,这种读取方式是输入字节流;

反过来,将 6 个字节存储到磁盘上,就是输出字节流

╔════════════╗
║   Memory   ║
╚════════════╝
       │0x21
       │0x6f
       │0x6c
       │0x6c
       │0x65
       │0x48
       ▼
 ╔═══════════╗
 ║ Hard Disk ║
 ╚═══════════╝
1
2
3
4
5
6
7
8
9
10
11
12
13

# Java 中的 IO 流

在 Java 中,有许多用于各种目的的 IO 类(例如读取文件的 IO 类,读取网络接口的 IO 类),我们可以简单地将它们分为输入类和输出类:

  • InputStream,代表输入字节流。是一个抽象类,所有输入流的超类。
  • OuputStream,代表输出字节流。也是抽象类,是所有输出流的超类。

图 17-1 程序通过输人对象接收数据,通过输出对象发送数据

图片来自《Java 语言程序设计-基础篇》17.1 节

除了字节之外,我们可能还会读写字符,因此 Java 提供了 Reader 和 Writer,用来读写字符;但是,计算机中只存储 0 和 1,Reader 和 Writer 本质上也是读取字节流的;只不过他们能在读取字节的时候自动解码为 char 字符,输出字节的时候自动编码为二进制数,所以看起来就是直接读写字符了:

图片来自《Java 语言程序设计-基础篇》17.2 节

我们也可以使用 InputStream 读取字符为 byte[] 数组,然后根据编码转换为字符串。

一般情况下,使用二进制文件的效率更高:

  1. 例如存储一个整数 199,只需存储 199 的二进制数字 C7 即可;而如果用文本文件,则需存储‘1’,‘9’,‘9’三个字符,需要存储的空间更大
  2. 二进制 IO 不需要编码和解码,比文本 IO 类效率高
  3. 二进制文件与主机的编码方案无关,因此是可移植的,在任何机器上的 Java 程序都可以读取 Java 程序所创建的二进制文件,这也是为什么编译后的字节码文件是二进制的原因。

# 同步和异步

同步 IO 是指,读写 IO 时代码必须等待数据返回后才继续执行后续代码,它的优点是代码编写简单,缺点是 CPU 执行效率低。

而异步 IO 是指,读写 IO 时仅发出请求,然后立刻执行后续代码,它的优点是 CPU 执行效率高,缺点是代码编写复杂。

Java 标准库的包 java.io 提供了所有同步 IO 的功能,而 java.nio 则提供了异步 IO。我们只讨论 Java 的同步 IO,对于异步 IO 感兴趣的同学可以去看看 Netty

上面我们讨论的 InputStream、OutputStream、Reader 和 Writer 都是同步 IO 的抽象类,要使用 IO 都得使用对应的具体实现类,以读写文件为例,有 FileInputStream、FileOutputStream、FileReader 和 FileWriter。

# 小结

什么是流:流是一种流式的数据输入/输出模型。

在 Java 中,java.io 包提供了同步 IO 功能。主要有两种流:

  • 字节流接口:InputStream/OutputStream,所有输入/输出流的父类,二进制数据以 byte 为最小单位流动;
  • 字符流接口:Reader/Writer,字符数据以 char 为最小单位流动

Java.nio 则提供了异步 IO。

上次更新: 2025/6/3 09:31:54
深入 BigDecimal
File 对象介绍

← 深入 BigDecimal File 对象介绍→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式