总结篇(21)---Java IO
Java IO:IO主要有两个重点:一是IO的架构模型,二是IO的操作一、IO的架构模型:目前主要有三大类:IO(BIO)、NIO、AIO。(1)IO(BIO):同步阻塞式IO,适用于连接数目比较小且固定的架构。线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一致阻塞,直到操作完成。(2)NIO:同步非阻塞式IO,适合于连接数目多且连接比较短(轻操作)的架构。(reactor模型)
Java IO:
IO主要有两个重点:一是IO的架构模型,二是IO的操作
一、IO的架构模型:
- 目前主要有三大类:IO(BIO)、NIO、AIO。
(1)IO(BIO):同步阻塞式IO,适用于连接数目比较小且固定的架构。
即一个线程发起IO请求后,一直阻塞直到操作完成。
- 当线程执行 read() 或 write() 系统调用时,数据未就绪前线程一直阻塞,直到数据拷贝完成才返回。每次连接都需要独立线程处理。

(2)NIO:同步非阻塞式IO,适合于连接数目多且连接比较短(轻操作)的架构。
即一个线程轮询检查多个连接的数据状态,只有数据真正准备好时才进行实际的读写。
- (reactor模型):通过 Selector 实现 I/O 多路复用。线程注册感兴趣的事件后即可轮询,数据就绪时再发起读写操作,但读写过程本身仍是阻塞的。

(3)AIO:异步非阻塞式IO,适用于连接数目多且连接比较长(重操作)的架构。
即一个线程发起IO请求后直接返回,当操作系统完成数据拷贝后,再主动通知线程来处理。
- (proactor模型)基于操作系统真正的异步 I/O 支持(如 Windows IOCP)。线程发起读写请求后立即返回,由内核完成数据拷贝后通过回调或 Future 通知应用程序。

总结与对比:
| 特性 | BIO (Blocking I/O) | NIO (Non-blocking I/O) | AIO (Asynchronous I/O) |
|---|---|---|---|
| 核心包 | java.io |
java.nio |
java.nio.channels |
| I/O 模型 | 同步阻塞 | 同步非阻塞 (多路复用) | 异步非阻塞 |
| 线程模型 | 一连接一线程 | 一线程管理多连接 (Selector) | 操作系统回调通知 |
| 数据操作 | 面向流 (单向) | 面向缓冲区 (Buffer) (双向) | 面向缓冲区 (Buffer) |
| 阻塞点 | read() / write() 处 |
仅在 select() 处可能阻塞 |
无阻塞,回调完成 |
| 适用场景 | 连接数少,低并发 | 连接数多,高并发 (短连接) | 连接数多,高并发 (长连接,文件) |
备注:
- 1、IO中同步和异步的区别:
同步和异步是相对于应用和内核的交互方式而言的。
同步需要主动去询问,而异步的时候内核在IO事件发生的时候通知应用程序。
- 2、IO中阻塞式和非阻塞式的区别:
阻塞式和非阻塞式是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取不同方式,说白了是一种读取或者写入操作函数的实现方式。
阻塞方式下读取或者写入函数将一直等待。
非阻塞式方式下,读取或者写入函数会立即返回一个状态值。
- 3、Reactor和Proactor模式的区别:
Reactor和Proactor模式的主要区别是真正的读取和写入操作是由谁来完成的。
Reactor中需要应用程序自己读取或写入数据。
而Proactor模式中,应用程序不需要进行实际的读写过程,它只需要从缓冲区读取或写入即可,操作系统会读取缓冲区或者写入缓冲区到真正的IO设备。
二、IO的操作:
我们先来实例一个IO操作:
/**
** Java文件读写操作
**/
//读文件
try{
FileInputStream fis = new FileInputStream("suncat.txt");
BufferedInputStream bis = new BufferInputStream(fis);
String content = null;
//自定义缓冲区
byte[] buffer = new byte[1024];
int flag = 0;
while( (flag = bis.read(buffer)) != -1){
content += new String(buffer,0,flag);
}
System.out.println(content);
//关闭的时候只需要关闭最外层的流就行了
bis.close();
}catch(Exception e){
e.printStackTrace();
}
//写文件
try{
FileOutputStream fos = new FileOutputStream("suncat.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String content = "xxxxxxxxxxx";
bos.write(content.getBytes(),0,content.getBytes().length);
bos.flush();
bos.close();
}catch(Exception e){
e.printStackTrace();
}
Java IO流共涉及40多个类,这些类看上去很杂乱,但实际上很有规律,而且彼此之间存在非常紧密的联系
Java IO流的40多个类都是从如下4个抽象基类中派生出来的。
(1)InputStream:字节输入流的基类
(2)OutputStream:字节输出流的基类
(3)Reader:字符输入流的基类
(4)Writer:字符输出流的基类
下图是按照操作方式的分类图:

其实,Java IO流中分类还有几种分类方式,不过都大同小异。
(1)按照流的流向分:输入流和输出流。
(2)按照操作单元划分:字节流和字符流。
(3)按照流的角色划分:节点流和处理流。
备注:
- 1.输入流和输出流的区别:
输入和输出的方向是针对程序而言,向程序中读入数据,就是输入流;从程序中向外写出数据,就是输出流。
- 2.字节流和字符流的区别:
以stream结尾都是字节流,以reader和writer结尾都是字符流,两者的区别就是读写的时候一个是按字节读写,一个是按字符。在实际使用时差不多。
在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。只是读写文件,和文件内容无关,一般选择字节流。
- 3.节点流和处理流的区别:
节点流和处理流的定义:
(1)节点流:可以从或者向一个特定的地方(节点)读写数据。
(2)处理流(用来包装节点流):是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
节点流和处理流的区别和联系:
(1)节点流是低级流,直接跟数据源相接。
处理流(也叫包装流)把节点流包装了一层,属于修饰器设计模式,不会直接与数据源相接,通过处理流来包装节点流可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
(2)处理流的功能主要体现在以下两个方面:
1)性能的提升:主要以增加缓冲的方式来提高输入输出的效率。
2)操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的内容,而不是输入/输出一个或多个。
更多java基础总结(适合于java基础学习、java面试常规题):
总结篇(9)---字符串及基本类 (1)字符串及基本类之基本数据类型
总结篇(10)---字符串及基本类 (2)字符串及基本类之java中公共方法及操作
总结篇(12)---字符串及基本类 (4)Integer对象
总结篇(14)---JVM(java虚拟机) (1)JVM虚拟机概括
总结篇(15)---JVM(java虚拟机) (2)类加载器
总结篇(16)---JVM(java虚拟机) (3)运行时数据区
总结篇(17)---JVM(java虚拟机) (4)垃圾回收
总结篇(18)---JVM(java虚拟机) (5)垃圾回收算法
总结篇(19)---JVM(java虚拟机) (6)JVM调优
总结篇(24)---Java线程及其相关(2)多线程及其问题
总结篇(25)---Java线程及其相关(3)线程池及其问题
总结篇(26)---Java线程及其相关(4)ThreadLocal
总结篇(27)---Java并发及锁(1)Synchronized
总结篇(31)---JUC工具类(1)CountDownLatch
总结篇(32)---JUC工具类(2)CyclicBarrier
更多推荐



所有评论(0)