NIO系列——缓冲区(Buffer)
Java NIO系统的核心在于:
通道(Channel)和缓冲区(Buffer)。通道表示打开到 IO 设备(例如:文件、套接字)的连接。
若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。
然后操作缓冲区,对数据进行处理。
简而言之,Channel 负责传输, Buffer 负责存储
概念:
缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
一个用于特定基本数据类型的容器。由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类。Java NIO 中的 Buffer 主要用于与 NIO 通道进行
交互,数据是从通道读入缓冲区,从缓冲区写
入通道中的。
缓冲区的类型:
* 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:
* ByteBuffer
* CharBuffer
* ShortBuffer
* IntBuffer
* LongBuffer
* FloatBuffer
* DoubleBuffer
*
* 上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区
* 二、缓冲区存取数据的两个核心方法:
* put() : 存入数据到缓冲区中
* get() : 获取缓冲区中的数据
*
* 三、缓冲区中的四个核心属性:
* capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
* limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
* position : 位置,表示缓冲区中正在操作数据的位置。
*
* mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置
*
* 0 <= mark <= position <= limit <= capacity
*
* 四、直接缓冲区与非直接缓冲区:
* 非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中
* 直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率
1 import java.nio.ByteBuffer; 2 3 import org.junit.Test; 4 5 /* 6 * 一、缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据 7 * 8 * 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区: 9 * ByteBuffer 10 * CharBuffer 11 * ShortBuffer 12 * IntBuffer 13 * LongBuffer 14 * FloatBuffer 15 * DoubleBuffer 16 * 17 * 上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区 18 * 19 * 二、缓冲区存取数据的两个核心方法: 20 * put() : 存入数据到缓冲区中 21 * get() : 获取缓冲区中的数据 22 * 23 * 三、缓冲区中的四个核心属性: 24 * capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。 25 * limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写) 26 * position : 位置,表示缓冲区中正在操作数据的位置。 27 * 28 * mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置 29 * 30 * 0 <= mark <= position <= limit <= capacity 31 * 32 * 四、直接缓冲区与非直接缓冲区: 33 * 非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中 34 * 直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率 35 */ 36 public class TestBuffer { 37 38 @Test 39 public void test3(){ 40 //分配直接缓冲区 41 ByteBuffer buf = ByteBuffer.allocateDirect(1024); 42 43 System.out.println(buf.isDirect()); 44 } 45 46 @Test 47 public void test2(){ 48 String str = "abcde"; 49 50 ByteBuffer buf = ByteBuffer.allocate(1024); 51 52 buf.put(str.getBytes()); 53 54 buf.flip(); 55 56 byte[] dst = new byte[buf.limit()]; 57 buf.get(dst, 0, 2); 58 System.out.println(new String(dst, 0, 2)); 59 System.out.println(buf.position()); 60 61 //mark() : 标记 62 buf.mark(); 63 64 buf.get(dst, 2, 2); 65 System.out.println(new String(dst, 2, 2)); 66 System.out.println(buf.position()); 67 68 //reset() : 恢复到 mark 的位置 69 buf.reset(); 70 System.out.println(buf.position()); 71 72 //判断缓冲区中是否还有剩余数据 73 if(buf.hasRemaining()){ 74 75 //获取缓冲区中可以操作的数量 76 System.out.println(buf.remaining()); 77 } 78 } 79 80 @Test 81 public void test1(){ 82 String str = "abcde"; 83 84 //1. 分配一个指定大小的缓冲区 85 ByteBuffer buf = ByteBuffer.allocate(1024); 86 87 System.out.println("-----------------allocate()----------------"); 88 System.out.println(buf.position()); 89 System.out.println(buf.limit()); 90 System.out.println(buf.capacity()); 91 92 //2. 利用 put() 存入数据到缓冲区中 93 buf.put(str.getBytes()); 94 95 System.out.println("-----------------put()----------------"); 96 System.out.println(buf.position()); 97 System.out.println(buf.limit()); 98 System.out.println(buf.capacity()); 99 100 //3. 切换读取数据模式 101 buf.flip(); 102 103 System.out.println("-----------------flip()----------------"); 104 System.out.println(buf.position()); 105 System.out.println(buf.limit()); 106 System.out.println(buf.capacity()); 107 108 //4. 利用 get() 读取缓冲区中的数据 109 byte[] dst = new byte[buf.limit()]; 110 buf.get(dst); 111 System.out.println(new String(dst, 0, dst.length)); 112 113 System.out.println("-----------------get()----------------"); 114 System.out.println(buf.position()); 115 System.out.println(buf.limit()); 116 System.out.println(buf.capacity()); 117 118 //5. rewind() : 可重复读 119 buf.rewind(); 120 121 System.out.println("-----------------rewind()----------------"); 122 System.out.println(buf.position()); 123 System.out.println(buf.limit()); 124 System.out.println(buf.capacity()); 125 126 //6. clear() : 清空缓冲区. 但是缓冲区中的数据依然存在,但是处于“被遗忘”状态 127 buf.clear(); 128 129 System.out.println("-----------------clear()----------------"); 130 System.out.println(buf.position()); 131 System.out.println(buf.limit()); 132 System.out.println(buf.capacity()); 133 134 System.out.println((char)buf.get()); 135 136 } 137 138 }