1 Java I/O:模型与流

在1990年以前,有一帮工程师们认为未来(1990年以后)会有很多小型设备需要得到电脑操控(不得不说,想法非常超前),鉴于当时市面上并没有任何一款编程语言能够跨平台,而且能够在诸如烤面包机这种小型设备上运转,所以他们决定自己创造一个,玩一把大的 。
于是Java诞生了 。
为了兼顾设备之间的文件处理 , Java在诞生之初就具备了文件读写能力,只不过那时候还是借用的Linux中的I/O概念 。因此可以说Java的I/O体系基本上就是Linux内核I/O模型的翻版 。
对于Linux而言,整个内部结构可分为三部分:底层硬件架构、内核空间和用户空间 。
内核空间中存放内核代码和数据 , 而用户空间中存放的是不同用户应用进程的代码和数据 。

1 Java I/O:模型与流

文章插图
不管是内核空间还是用户空间 , 它们都处于虚拟存储空间(寻址空间)中——现在很多计算机都是64位操作系统的 , 那么理论上,它的寻址空间就是2的64次方(264):
1 Java I/O:模型与流

文章插图
具体Linux怎么工作的就不说了,总之很牛逼 。
从Java I/O出现以来,已经经历了五种模型(知道就好了,不用记,也记不?。?记住了也用不着):
1、阻塞I/O(Blocking I/O)
1 Java I/O:模型与流

文章插图
2、非阻塞I/O(Non-Blocking I/O , 又叫NIO)
1 Java I/O:模型与流

文章插图
3、I/O复用
1 Java I/O:模型与流

文章插图
4、信号驱动I/O(Signal Driven I/O)
1 Java I/O:模型与流

文章插图
5、异步I/O(Asynchrnous I/O,又叫AIO)
1 Java I/O:模型与流

文章插图
这五种I/O模型的分类是:
1 Java I/O:模型与流

文章插图
看看这些图就可以了 , 也不需要深究,重点还是要了解Java代码怎么写 。
早期的Java I/O都是基于阻塞I/O模型的,也就是BIO,它分为两个部分:流式部分和非流式部分 。Java对流的定义是:流是一组有顺序的,有起点和终点的字节集合,是对数据传输的抽象——数据在设备间的传输称为流(后面的流式编程还会提到它) 。
流式部分:是根据不同的数据流向 , 分为输入流Input和输出流Output,对输入流只能进行读操作,对输出流只能进行写操作 。根据不同的数据编码,又分为字节流Byte和字符流Char , 字符流的本质其实就是基于字节流读取时,通过指定的编码表将字节转换为字符,字节流可以处理所有的数据类型,而字符流只能处理字符类型的数据 。
非流式部分:包含一些辅助类,如File、FileDescriptor、RandomAccessFile、SerializablePermission等,也就是直接操作具体的文件 。
按数据格式,流可以分为:
字节流:以8位(即1byte,8bit)作为一个数据单元 , 数据流中最小的数据单元是字节 。
字符流:以16位(即1char , 2byte,16bit)作为一个数据单元,数据流中最小的数据单元是字符 , Java中的字符是Unicode编码,一个字符占用两个字节 。
依据字节流 , Java定义了抽象基类InputStream/OutputStream 。
而依据字符流,Java定义了抽象基类Reader/Writer 。
然后Java再根据不同应用场景或功能,通过继承这两种抽象基类派生出子类 , 用来满足文件、网络、管道等不同场景的I/O需求,从而形成了Java的基本I/O体系 。
1 Java I/O:模型与流

文章插图
按用途,流又可以分为处理流与装饰流:
1 Java I/O:模型与流

文章插图
按操作方式分类:
1 Java I/O:模型与流

文章插图
按操作对象分类:
1 Java I/O:模型与流

文章插图
一般用虚线连接的类会搭配使用:
1 Java I/O:模型与流

文章插图

1 Java I/O:模型与流

文章插图
在高性能的I/O应用中,有几个名词经常出现:同步/异步、阻塞/非阻塞、同步阻塞/同步非阻塞、异步阻塞/异步非阻塞 。

推荐阅读