Java NIO 缓冲区(Buffer)讲解和实战demo

Java NIO(New IO)是一种非阻塞 IO 的实现方式,相比传统的阻塞 IO,在处理高并发请求时能够提供更高的性能。NIO 采用了基于缓冲区的读写机制,而非传统的流式 IO,这也是其相比传统 IO 更高效的原因之一。本文将详细讲解 Java NIO 缓冲区的知识点,并附上相关的示例代码。

缓冲区介绍

Java NIO 的缓冲区是一个内存块,可以在缓冲区中读写数据。缓冲区实际上是一个数组,可以保存不同类型的数据,如 byte、short、int、long、float、double 等基本数据类型,以及它们的派生类型 CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer 等。

缓冲区的基本属性

容量(capacity):缓冲区能够容纳的数据元素的最大数量,它在缓冲区创建时被设定,并且不能被改变。
上界(limit):缓冲区中可以操作的数据元素的最大数量,它在缓冲区创建时被设定,并且不能被改变。
位置(position):下一个要读取或写入的数据元素的位置,它初始值为 0。
标记(mark):一个备忘位置,用于记录当前 position 的前一个位置或者其他信息。

缓冲区的状态变化示意图:

初始状态 position = 0
        |
        V
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+
 ↑               ↑
 |               |
mark            limit

缓冲区的类型

Java NIO 中提供了 8 种类型的缓冲区,每种缓冲区都有其特定的应用场景,具体如下:

ByteBuffer:最常用的缓冲区类型,用于处理原始的字节数据。
CharBuffer:处理字符数据,如 ASCII 码等。
ShortBuffer:处理短整型数据。
IntBuffer:处理整型数据。
LongBuffer:处理长整型数据。
FloatBuffer:处理浮点型数据。
DoubleBuffer:处理双精度浮点型数据。
MappedByteBuffer:内存映射文件缓冲区,可用于内存映射文件的 IO 操作。

缓冲区的创建和使用

缓冲区的创建通常有两种方式:allocate 和 wrap。

allocate 方式

allocate 方式是通过 ByteBuffer.allocate() 方法来创建指定大小的缓冲区。

wrap 方式

wrap 方式是通过 ByteBuffer.wrap() 方法来创建指定数据的缓冲区。

下面是一个简单的 Java NIO 缓冲区(Buffer)代码示例:

import java.nio.*;

public class BufferDemo {
    public static void main(String[] args) {
        // 分配一个容量为10的int类型缓冲区
        IntBuffer intBuffer = IntBuffer.allocate(10);

        // 向缓冲区中放入数据
        for (int i = 0; i < intBuffer.capacity(); i++) {
            intBuffer.put(i);
        }

        // 将缓冲区转换为读模式
        intBuffer.flip();

        // 读取缓冲区中的数据
        while (intBuffer.hasRemaining()) {
            int num = intBuffer.get();
            System.out.print(num + " ");
        }
    }
}

该示例分配了一个容量为10的int类型缓冲区,然后向缓冲区中放入数据,接着将缓冲区转换为读模式,最后读取缓冲区中的数据并输出。输出结果为:

0 1 2 3 4 5 6 7 8 9

其中,IntBuffer是一个int类型的缓冲区类,通过allocate方法可以分配一个指定大小的缓冲区。put方法用于向缓冲区中放入数据,flip方法将缓冲区转换为读模式,hasRemaining方法用于判断是否还有剩余元素未读取,get方法用于读取缓冲区中的数据。