Java中的NIO模型详解

208 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第46天,点击查看活动详情 >>

Java中的NIO模型详解

之前我们已经介绍过了如何使用Java来模拟BIO模型,那么今天我们就接着来学习Java是如何模拟NIO模型的

NIO模型的定义解析:

NIO模型,又称为同步非阻塞模型,它是面向缓冲区的,或者说是面向块的;在Java NIO中它主要有三大核心部分:

  1. Cannel(通道)
  2. Buffer (缓冲区)
  3. Selector(选择器)

NIO的使用场景

因为NIO是同步非阻塞的,它是面向缓冲区编程的,所以基于这样的特性,它的主要使用场景:适用于连接数目比较多而且连接都是比较短(轻操作) 的架构, 比如聊天服务器, 弹幕系统, 服务器间通讯等 这类。

Java代码举例子实现NIO读取

具体的需求如下:

  1. 创建一个int型的buffer缓冲区
  2. 通过for 循环往int型的缓冲区中加入数据
  3. 将int型buffer缓冲区反转(注意这里是一步非常核心的操作,一定不要漏了,否则将出现异常)
  4. 循环将刚刚输入到缓冲区的数据数出来(输出到控制台)

了解了具体的需求之后,我们就可以上手看代码的实现了。

缓冲区的代码:

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模型了。