一、I/O & NIO
Java的IO流,根据类型不同划分为(具体继承这些IO类的子类非常多)
- 基于字节操作的 I/O 接口:InputStream 和 OutputStream
- 基于字符操作的 I/O 接口:Writer 和 Reader
- 基于磁盘操作的 I/O 接口:File
- 基于网络操作的 I/O 接口:Socket
Java传统的IO类操作都是阻塞的,在高并发的场景下性能令人堪忧。
Java NIO(Non-blocking IO)是JDK1.4之后推出的一套新IO接口——非阻塞IO,与传统IO接口的主要区别在于:
| I/O |
NIO |
| 线程阻塞 |
线程非阻塞 |
| 用流(Stream)的方式处理数据 |
用缓冲区(Buffer)的方式处理数据 |
二、NIO基本概念
- Channel(通道)
- Buffer(缓冲区)
- Selector(选择器)
2.1 Channel
1). Channel,相对于Stream,有几点区别:
| Channel |
Stream |
| 双向(可以读写) |
单向(只能读或只能写) |
| 非阻塞操作 |
阻塞操作 |
| 基于Buffer |
基于流 |
2). NIO数据的流向总是:
Channel ----> Buffer
Channel <---- Buffer
3). Channel主要有下面几种类型:
| 类型 |
说明 |
| FileChannel |
文件的数据读写 |
| DatagramChannel |
UDP的数据读写 |
| SocketChannel |
TCP的数据读写 |
| ServerSocketChannel |
监听TCP链接请求,并且创建SocketChannel |
4). 具体获取Channel的类
| 类型 |
说明 |
| FileChannel |
FileInputStream.getChannel() FileOutputStream.getChannel() RandomAccessFile.getChannel() |
| DatagramChannel |
DatagramChannel.open() |
| SocketChannel |
SocketChannel.open() |
| ServerSocketChannel |
ServerSocketChannel.open() |
2.2 Buffer
Buffer实际上就是一块内存区,用于和Channel交互,需要注意的是:
Buffer是非线程安全的,如果需要在多线程环境中使用,则需要有同步锁。
1). Buffer基本概念
要真正理解Buffer,有一张图比较经典:
- capacity: buffer的容量大小,一般在创建之后就不会再改变;
- limit: buffer内存区中还未被读写的第一个element位置索引;
- position: 下一个等待要被读写的element位置索引;
- mark: 当调用reset方法时,position会被重置的位置索引;
通常,0 <= mark <= position <= limit <= capacity

2). Buffer类型
| Buffer名字 |
对应基础类型 |
| ByteBuffer |
byte |
| CharBuffer |
char |
| DoubleBuffer |
double |
| FloatBuffer |
float |
| IntBuffer |
int |
| LongBuffer |
long |
3). Buffer常用操作
| buffer操作 |
具体 |
| clear() |
limit=capacity, position=0, mark忽略 |
| flip() |
limit= position, position=0, mark忽略 |
| rewind() |
position=0, mark忽略 |
compact() (ByteBuffer才有) |
将整块Buffer(从position~limit)移动到Buffer开始的位置(0~limit-position) |
Buffer常用操作模式:
- 把数据写入buffer;
- 调用flip;
- 从buffer中读取数据;
- 调用buffer.clear()清空整个buffer 或者 buffer.compact()清空已经读取的buffer
2.3 Selector
Selector是NIO中的组件,检查一个或多个channel,实现一个线程管理多个网络链接。

使用步骤:
- 创建 selector
- 注册channel到selector
Channel必须是非阻塞的。所以FileChannel不适用Selector,因为FileChannel不能切换为非阻塞模式。Socket channel可以正常使用。
参考链接
一、I/O & NIO
Java的IO流,根据类型不同划分为(具体继承这些IO类的子类非常多)
Java传统的IO类操作都是阻塞的,在高并发的场景下性能令人堪忧。
Java NIO(Non-blocking IO)是JDK1.4之后推出的一套新IO接口——非阻塞IO,与传统IO接口的主要区别在于:
二、NIO基本概念
2.1 Channel
1). Channel,相对于Stream,有几点区别:
2). NIO数据的流向总是:
Channel ----> Buffer
Channel <---- Buffer
3). Channel主要有下面几种类型:
4). 具体获取Channel的类
FileOutputStream.getChannel()
RandomAccessFile.getChannel()
2.2 Buffer
Buffer实际上就是一块内存区,用于和Channel交互,需要注意的是:
Buffer是非线程安全的,如果需要在多线程环境中使用,则需要有同步锁。
1). Buffer基本概念
要真正理解Buffer,有一张图比较经典:
通常,0 <= mark <= position <= limit <= capacity
2). Buffer类型
3). Buffer常用操作
(ByteBuffer才有)
Buffer常用操作模式:
2.3 Selector
Selector是NIO中的组件,检查一个或多个channel,实现一个线程管理多个网络链接。
使用步骤:
Channel必须是非阻塞的。所以FileChannel不适用Selector,因为FileChannel不能切换为非阻塞模式。Socket channel可以正常使用。
参考链接