缓冲区(Buffer):一个用于特定基本数据类型的容器。由java.nio包定义的,所有缓冲区都是Buffer抽象类的子类

    • 缓冲区的类型:

    缓冲区(Buffer):在Java NIO中负责数据的存取。缓冲区就是数组,用于存储不同类型的数据,根据类型的不同(除boolean),都提供了相应类型的缓冲区:
    ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer
    缓冲区的管理方式基本一致,都是通过allocate()来获取

    • 缓冲区存取数据的两个核心方法:
    1. put():存入数据到缓冲区
    2. get():获取缓冲区中的数据
    • 缓冲区中的四个核心属性
    1. capacity:容量,标识缓冲区中最大存储数据的容量,声明后不能更改
    2. limit:接线,标识缓冲区中可以操作数据的大小,limit后的数据不能进行读写操作
    3. position:位置,表示缓冲区中正在操作数据的位置
    4. mark:标记,表示记录当前position的位置,可以通过reset()恢复到mark的位置

    image.png

    这些属性之间的大小遵循的顺序:
    0 <= mark <= position <= limit <=capacity

    1. public class BufferDemo {
    2. public static void demo1() {
    3. String str = "abcde";
    4. // 分配一个指定大小的缓冲区
    5. ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    6. System.out.println("---------allocate-----------");
    7. System.out.println(byteBuffer.capacity()); // 1024
    8. System.out.println(byteBuffer.limit()); // 1024
    9. System.out.println(byteBuffer.position()); // 0
    10. // 利用 put() 存入数据到缓冲区中
    11. byteBuffer.put(str.getBytes());
    12. System.out.println("---------put-----------");
    13. System.out.println(byteBuffer.capacity()); // 1024
    14. System.out.println(byteBuffer.limit()); // 1024
    15. System.out.println(byteBuffer.position()); // 5
    16. // 切换到读数据模式
    17. byteBuffer.flip();
    18. System.out.println("---------flip-----------");
    19. System.out.println(byteBuffer.capacity()); // 1024
    20. System.out.println(byteBuffer.limit()); // 5,limit 表示可以操作数据的大小,只有 5 个字节的数据给你读,所以可操作数据大小是 5
    21. System.out.println(byteBuffer.position()); // 0,读数据要从第 0 个位置开始读
    22. // 利用 get() 读取缓冲区中的数据
    23. byte[] dst = new byte[byteBuffer.limit()];
    24. byteBuffer.get(dst);
    25. System.out.println(new String(dst, 0, dst.length));
    26. System.out.println("---------get-----------");
    27. System.out.println(byteBuffer.capacity()); // 1024
    28. System.out.println(byteBuffer.limit()); // 5,可以读取数据的大小依然是 5 个
    29. System.out.println(byteBuffer.position()); // 5,读完之后位置变到了第 5 个
    30. // rewind() 可重复读
    31. byteBuffer.rewind(); // 这个方法调用完后,又变成了读模式
    32. System.out.println("---------rewind-----------");
    33. System.out.println(byteBuffer.capacity()); // 1024
    34. System.out.println(byteBuffer.limit()); // 5
    35. System.out.println(byteBuffer.position()); // 0
    36. // clear()
    37. // 清空缓冲区,虽然缓冲区被清空了,但是缓冲区中的数据依然存在,只是出于"被遗忘"状态。意思其实是,缓冲区中的界限、位置等信息都被置为最初的状态了,所以你无法再根据这些信息找到原来的数据了,原来数据就出于"被遗忘"状态
    38. byteBuffer.clear();
    39. System.out.println("---------clear-----------");
    40. System.out.println(byteBuffer.capacity()); // 1024
    41. System.out.println(byteBuffer.limit()); // 1024
    42. System.out.println(byteBuffer.position()); // 0
    43. }
    44. public static void demo2() {
    45. String str = "abcde";
    46. ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    47. byteBuffer.put(str.getBytes());
    48. byteBuffer.flip();
    49. byte[] bytearray = new byte[byteBuffer.limit()];
    50. byteBuffer.get(bytearray, 0, 2);
    51. System.out.println(new String(bytearray, 0, 2)); // 结果是 ab
    52. System.out.println(byteBuffer.position()); // 结果是 2
    53. // 标记一下当前 position 的位置
    54. byteBuffer.mark();
    55. byteBuffer.get(bytearray, 2, 2);
    56. System.out.println(new String(bytearray, 2, 2));
    57. System.out.println(byteBuffer.position()); // 结果是 4
    58. // reset() 恢复到 mark 的位置
    59. byteBuffer.reset();
    60. System.out.println(byteBuffer.position()); // 结果是 2
    61. // 判断缓冲区中是否还有剩余数据
    62. if (byteBuffer.hasRemaining()) {
    63. // 获取缓冲区中可以操作的数量
    64. System.out.println(byteBuffer.remaining()); // 结果是 3,上面 position 是从 2 开始的
    65. }
    66. }
    67. }