IO的分类
BIO(Blocking I/O):同步阻塞IO
以电脑为中心,InputStream(Reader)就是将外部数据以流的形式加载到电脑的内存中,OutputStream(Writer)就是把内存中的数据以流的形式向外输出。
字节流:以xxStream
命名,一般成对出现,如InputStream
,OutputStream
常见的字节流:
- 文件流:
FileInputStream
,FileOutputStream
–用于处理文件 - 过滤流:
FilterInputStream
,FilterOutputStream
–套在InputStream
和OutputStream
外层,提供一些方便的功能
BufferedInputStream
,BufferedOutputStream
–提供缓冲区功能,提升效率- 其他:
DataInputStream
,DataOutputStream
,PrintStream
,PushbackInputStream
…
- 字节数组流:
ByteArrayInputStream
,ByteArrayOutputStream
–将数据写入内部数据,数组大小随着数据写入而动态扩展 - 管道流:
PipedInputStream
,PipedOutputStream
–用于多线程间管道通信 - 对象流:
ObjectInputStream
,ObjectOutputStream
–用于对象和流之间转换
字符流:以xxReader
(xxWriter
)命名,功能类型同上
BufferedReader
,BufferedWriter
CharArrayReader
,CharArrayWriter
PipedReader
,PipedWriter
PushbackReader
,PrintWriter
StringReader
,StringWriter
InputStreamReader
,OutputStreamWriter
–将字节流转为字符流(注意编码)
FileReader
,FileWriter
NIO(New I/O):同步非阻塞IO(也支持同步阻塞IO) –since jdk1.4
Java的NIO模型,底层依赖的是操作系统的NIO模型;因此,windows和Linux下的底层实现是不同的。(linux版本大于2.6的话用的是EPoll,小于2.6用的Poll)。
标准IO中,数据打包是以流
的形式,而NIO中是以块
的形式处理,这样速度更快。
Channel
通道Channel
是一个对象,用来读写数据。它是对流Stream
的模拟,但是流区分方向(Input/Output),而通道没有方向的概念,可以读也可以写。所有数据,都是从通道读入到缓冲区Buffer
,或者从缓冲区写入通道。
常用Channel
* FileChannel
* DatagramChannel
* SocketChannel
* ServerSocketChannel
Buffer
缓冲区Buffer
是一个对象,可以看做一个容器,用来存放数据(刚读入的数据,或者要写出去的数据)。在NIO中,所有的数据都是在缓冲区里处理的。缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。
常用Buffer:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
Selector
选择器Selector
用来监听1个或多个通道(是否准备好读写),从而实现一个线程管理多个通道。线程之间切换,性能开销较大,因此,用一个线程来维护所有通道比较好。
AIO(Asynchronous I/O, NIO 2.0):异步非阻塞IO –since jdk1.7
从编程模式上来看AIO相对于NIO的区别在于,NIO需要使用者线程不停的轮询IO对象,来确定是否有数据准备好可以读了,而AIO则是在数据准备好之后,才会通知数据使用者,这样使用者就不需要不停地轮询了。当然AIO的异步特性并不是Java实现的伪异步,而是使用了系统底层API的支持,在Unix系统下,采用了epoll IO模型,而windows便是使用了IOCP模型。