Java NIO原理及使用
运行环境:idea2018,jdk11
简述
1、比较
IO | NIO | |
数据处理 | 字节或字符流(stream) | 块(channel) |
方向 | 单向(InputStream/OutputStream) | 双向(读写) |
2、NIO(Non-blocking I/O),非阻塞IO,也可以理解为新IO(new I/O)。相对于传统的IO以字节或字符或单位传输,NIO以数据块的方式批量传输。突出的有点就是快速和简单,在网络传输中优势明显。
3、NIO具有双向读写功能,支持一个缓存中同时包含读写功能。
4、@since jdk1.4
通道Channel
NIO是在IO的基础上集成出来的,而通道channel类似I/O中的流,通过它进行读写操作,且方向是双向的。
通道在包java.nio.channels
下,主要有以下4种类型
类 | 功能 | channel for |
FileChannel | 从文件中读写数据 | reading, writing, mapping, and manipulating a file. |
DatagramChannel | 通过 UDP 读写网络中数据 | datagram-oriented sockets. |
SocketChannel | 通过 TCP 读写网络中数据 | stream-oriented connecting sockets |
ServerSocketChannel | 监听新进来的TCP 连接 | stream-oriented listening sockets |
缓冲区
IO中缓冲充当装饰类,非必须。而NIO中,一个通道的所有数据必须先放到缓冲区,再进行读写数据,不能直接操作通道进行读写。底层是一个数组。
读写演示
1、为通道新建一个8个字节缓冲区,则最大容量capacity
为8,还可以读写的字节数limit
也为8,
指针posistion
指向下一个待读写的位置,即当前已经读写的字节数。
2、从输入通道中读取 4个字节数据写入缓冲区,posittion指针指向下一个位置4,limit不变。
3、将缓冲区写入输出通道,先调用flip()
,该方法flip缓存,limit设置到当前position位置,并且limit标记到4,然后position设置为0。
4、从缓冲区中取 4 个字节到输出缓冲中,此时 position 设为 4。
5、最后需要调用 clear()
方法,该方法清空缓存,position设置到0,limit设置到capacity。
代码演示
使用nio,从d盘中的aaa.txt文件拷贝到e盘。
public class TestNIO {
@Test
public void testCopy(){
try {
// 创建输入流
FileInputStream in = new FileInputStream("D:\\aaa.txt");
// 创建输入通道
FileChannel inChannel = in.getChannel();
// 创建输出流
FileOutputStream out = new FileOutputStream("E:\\aaa.txt");
// 创建通道
FileChannel outChannel = out.getChannel();
// 创建缓存,大小1024字节
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
// 循环读写
while (true){
// 从通道读取序列的自接到给定缓冲区,更新position位置
int read = inChannel.read(buffer);
// 全部读完退出
if (read==-1){
break;
}
// flip缓存,position回到0
buffer.flip();
// 缓冲区写道输出通道
outChannel.write(buffer);
// 清空,limit回到capacity
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
复制代码
拷贝完成!