IO-输入输出
Java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象
真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据
java.io 包里面定义了所有的流,所以一说流指的就是java.io 包里面的
IO流的分类
输入流和输出流
输入流和输出流都是站在程序的角度上来说,更准确地讲,其实输入输出是相对
于内存而言的,输入输出相对于内存而言更加准确,也不容易混淆
数据流向 内存---->输入流
数据流出 内存---->输出流
字节流和字符流
1.字节流处理的最基本单位为单个字节,即1 Byte 占8 bit位
2.字符流处理的最基本的单元是Unicode码元,其大小为2个字节,2 Byte 16 bit位
3.字节流默认不使用缓冲区;字符流使用缓冲区
4.字节流通常用于处理二进制数据,不支持直接写入或读取Unicode码元
5.字符流通常处理文本数据,它支持写入及读取Unicode码元
节点流和处理流
节点流:可以从特定的数据源读取数据(文件、内存)的流
节点流就是一根管道直接插到数据源上面,直接读数据源里面的数据
或者是直接往数据源里面写入数据!
1.文件:典型的节点流
FileReader
FileWriter
FileInputStream
FileOutputStream
2.Memory Array
CharArrayReader
CharArrayWriter
ByteArrayInputStream
ByteArrayOutputStream
3.Memory String
StringReader
StringWriter
4.Pipe(管道)
PipeReader
PipeWriter
PipeInputStream
PipeOutputStream
处理流:“”连接“”在已存在的流(节点流或处理流)上,通过对数据的处理为程序提供更为强大的读写能力
重要的IO流及其基本方法
InputStream:
凡是以InputStream结尾的管道,都是以字节的形式向程序输入数据
read()方法是一个字节一个字节地往外读,每读取一个字节,就处理一个字节
read(byte[] buffer)方法读取数据时,一堆一堆的读取
OutputStream
AIO BIO NIO
io操作分为两部分,发起io请求,和io数据读写:
阻塞、非阻塞主要是针对线程发起io请求后,是否立即返回来定义的
立即返回称为非阻塞io,否则称为阻塞io
同步、异步主要针对io数据读写来定义的,读写数据过程中不阻塞线程称为异步io,否则,称为同步io
BIO:BIO 是 BlockingIO 的缩写,表示同步阻塞式IO
线程发起io请求后,一直阻塞(阻塞io),直到数据就绪后,
用户线程将数据写入socket空间,或从socket空间读取数据(同步)
服务器实现模式为一个连接一个线程,
客户端有连接请求时服务器端就需要启动一个线程进行处理
如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善
BIO适用于连接数目比较小且固定的架构,该方式对服务器资源要求比较高
NIO:表示同步非阻塞IO
线程发起io请求后,立即返回(非阻塞io)。用户线程不阻塞等待,
但是,用户线程要定时轮询检查数据是否就绪,当数据就绪后,
用户线程将数据从用户空间写入socket空间,或从socket空间读取数据到用户空间(同步)
IO多路复用(NIO)
将检查IO数据是否就绪的任务,交给系统级别的select或poll模型,由系统进行监控,减轻用户线程负担
当用户线程发起io请求后,将socket连接及关注事件注册到selector(多路复用器,os级别线程)上
selector循环遍历socket连接,看是否有关注数据就绪,如果连接有数据就绪后,就通知应用程序,
建立线程进行数据读写
epoll:基于事件驱动思想,采用reactor模式,通过事件回调,无需使用某种方式主动检查socket状态
服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上
多路复用器轮询到连接有I/O请求时才启动一个线程进行处理
NIO适用于连接数目多且连接比较短(轻操作)的架构,如在Netty框架中使用
AIO:表示异步非阻塞IO
线程发起io请求后,立即返回(非阻塞io),当数据读写完成后,OS通知用户线程(异步)。
这里数据写入socket空间,或从socket空间读取数据到用户空间由OS完成,用户线程无需介入,
所以也就不会阻塞用户线程,即异步
AIO基于时间驱动思想,采用proactor模式。数据完成后,由os主动通知应用程序
服务器实现模式为一个有效请求一个线程,
客户端的I/O请求都是由操作系统先完成IO操作后再通知服务器应用来启动线程进行处理
AIO适用于连接数目多且连接比较长(重操作)的架构