从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • 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新特性

    • 网络编程

    • Java
  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

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

IO介绍

# 00.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。

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2023/2/10 08:54:20
BigDecimal小结
File对象介绍

← BigDecimal小结 File对象介绍→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式