携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第46天,点击查看活动详情 >>
Java中的NIO模型详解
之前我们已经介绍过了如何使用Java来模拟BIO模型,那么今天我们就接着来学习Java是如何模拟NIO模型的
NIO模型的定义解析:
NIO模型,又称为同步非阻塞模型,它是面向缓冲区的,或者说是面向块的;在Java NIO中它主要有三大核心部分:
- Cannel(通道)
- Buffer (缓冲区)
- Selector(选择器)
NIO的使用场景
因为NIO是同步非阻塞的,它是面向缓冲区编程的,所以基于这样的特性,它的主要使用场景:适用于连接数目比较多而且连接都是比较短(轻操作) 的架构, 比如聊天服务器, 弹幕系统, 服务器间通讯等 这类。
Java代码举例子实现NIO读取
具体的需求如下:
- 创建一个int型的buffer缓冲区
- 通过for 循环往int型的缓冲区中加入数据
- 将int型buffer缓冲区反转(注意这里是一步非常核心的操作,一定不要漏了,否则将出现异常)
- 循环将刚刚输入到缓冲区的数据数出来(输出到控制台)
了解了具体的需求之后,我们就可以上手看代码的实现了。
缓冲区的代码:
public class BasicBuffer {
public static void main(String[] args) {
// 创建一个 buffer ,可存 5 个 int型的数据
IntBuffer intBuffer = IntBuffer.allocate(5);
// 通过for循环,循环向 buffer 中放数据
for (int i = 0; i < intBuffer.capacity(); i++) {
intBuffer.put(i * 2);
}
// 读取缓冲区的数据
// 反转缓冲区:从读缓冲区变为写缓冲区
// 实际上它就是将索引(position)从最后的位置移动到了最开始的位置
intBuffer.flip();
while (intBuffer.hasRemaining()) {
// 这里每get获取到一个数据,索引就会向后移动一位,这里的操作就有点像是入栈时候那样
System.out.println(intBuffer.get());
}
}
}
在这里还有一点需要注意的就是:代码intBuffer.get()get中如果不指定position的位置的话,就是将数据一个一个输出。
但是如何有指定位置的话,就输出指定位置的数据,举个例子大家就懂了:
System.out.println(intBuffer.get(3));
上面代码中就指定了get(3),所以说它只会输出索引(position)为 3 所对应的数据。
NIO写文件:
public static void main(String[] args) throws Exception {
String s = "hello, how are you";
File file = new File("src/main/java/com/nio/channel/file01");
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
// 通过输出流获取通道
// FileChannel 真实是 FileChannelImpl
FileChannel fileChannel = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.put(s.getBytes());
// 缓冲区反转,从读缓冲区变成写缓冲区
byteBuffer.flip();
// 将缓冲区的数据写到通道上
fileChannel.write(byteBuffer);
fileOutputStream.close();
}
总结:
在NIO模型方面,它采用了缓冲区和通道等技术提升了读写性能,使得NIO模型在更多场景下适用,目前适用得最多的就是NIO模型了。