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 }
纸上学来终觉浅,觉知此事需躬行
原文地址:https://www.cnblogs.com/dreamHighMjc/p/8185217.html