NIO时JDK1.4以后引入的,弥补了原咯爱IO的不足;
1、流与块:
IO和NIO的区别:
(1)IO一次处理一个字节,输入/输出均为一个字节
(2)NIO方式一次处理一个数据块
2、通道与缓冲区:
(1)通道(Channel):
通道是对原来的IO的流的模拟,与IO最大的区别在于IO只能是单向的要么输入要么输出,而通道则可以同时读也可以同时写。
通道包括:
- FileChannel:从文件中读写数据;
- DatagramChannel:通过 UDP 读写网络中数据;
- SocketChannel:通过 TCP 读写网络中数据;
- ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
(2)缓冲区:
发送到通道的数据都被首先存放在缓冲区中:
缓冲区包括:
![](/qrcode.jpg)
- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
(3)缓冲区变量内部过程:
状态变量三个值指定缓冲区任意时刻状态:
-
position(跟踪已经写了多少数据)
-
limit(表明还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时))
-
capacity(表明可以储存在缓冲区中的最大数据容量)
position 总是小于或者等于 limit,limit 决不能大于 capacity。
例如,Buffer状态如下:
limit 决不能大于 capacity,此例中这两个值都被设置为 8。我们通过将它们指向数组的尾部之后(如果有第8个槽,则是第8个槽所在的位置)来说明这点
1>、开始读取数据,存入缓冲区时,position设置为0,即指向第一个位置
第一次读取3个数据,则position位置指向第四个位置(0 + 3 = 3), limit不变化:
第二次读取2个数据,则position指向第6个位置(3+2=5),limit不变化:
2>、flip操作时
-
它将 limit 设置为当前 position。
-
它将 position 设置为 0
3>、开始数据写入时,从缓冲区取出数据写入通道:
第一次写入,向通道写入4个字节数据,position指向第5个位置,limit指向第6个位置:
第二次写入,向通道写入1个字节,则position位置变为6,此时limit等于position:
4>、最后clear
-
它将 limit 设置为与 capacity 相同。
-
它设置 position 为 0。
3、文件NIO实例:
public static void fastCopy(String src, String dist) throws IOException {
/* 获得源文件的输入字节流 */
FileInputStream fin = new FileInputStream(src);
/* 获取输入字节流的文件通道 */
FileChannel fcin = fin.getChannel();
/* 获取目标文件的输出字节流 */
FileOutputStream fout = new FileOutputStream(dist);
/* 获取输出字节流的文件通道 */
FileChannel fcout = fout.getChannel();
/* 为缓冲区分配 1024 个字节 */
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (true) {
/* 从输入通道中读取数据到缓冲区中 */
int r = fcin.read(buffer);
/* read() 返回 -1 表示 EOF */
if (r == -1) {
break;
}
/* 切换读写 */
buffer.flip();
/* 把缓冲区的内容写入输出文件中 */
fcout.write(buffer);
/* 清空缓冲区 */
buffer.clear();
}
}