【Java】如何使用 Java 中 缓冲区类 Buffer
如何使用 Java 中 缓冲区类 Buffer
1. 什么是Buffer 缓冲区
缓冲区(Buffer):就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区 缓冲区本质上是一个可以读写数据的内存块,可以理解成是一个数组,该对象提供了一组方法,可以更轻松地使用内存块
2.Buffer及其常用子类
从 JDK1.4开始,提供使用Buffer类
3.Buffer 相关API介绍
方法名 | 说明 |
---|---|
int position() / position(int newPosition) | 获得当前要操作的索引/修改当前要操作的索引位置 |
int limit() / limit(int newLimit) | 最多能操作到哪个索引/修改最多能操作的索引位置 |
int capacity() | 返回缓冲区的总长度 |
int remaining() /boolean hasRemaining() | 还有多少能操作索引个数/是否还有能操作 |
put(byte b)/put(byte[] src) | 添加一个字节/添加字节数组 |
flip() | 切换读模式 limit设置position位置, position设置0 |
rewind() | 将position设置为0,可以重复读 |
clear() | 换写模式 position设置为0 , limit 设置为 capacity |
get() | 读一个字节 |
get(byte[] dst) | 读多个字节 |
get(int index) | 读指定索引的字节 |
ByteBuffer bbf = ByteBuffer.allocate(10); System.out.println("当前索引"+bbf.position()); System.out.println("最大索引位置"+bbf.limit()); System.out.println("能操作索引长度"+bbf.remaining()); System.out.println("缓冲区总长度"+bbf.capacity());
4.创建Buffer实例
方式一 : 指定缓冲区的容量
//方式一: 指定容量为10个字节 ByteBuffer allocate = ByteBuffer.allocate(10);
public static ByteBuffer allocate(int capacity)分配一个新的字节缓冲区。 新缓冲区的位置将为零,其限制将为其容量,其标记将不定义,并且其每个元素将被初始化为零。 它将有一个backing array ,其array offset将为零。 参数 capacity - 新的缓冲区的容量,以字节为单位 结果 新的字节缓冲区 异常 IllegalArgumentException - 如果 capacity是负整数
方式二: 指定缓存区内容与容量
//方式二: 指定数组内容 ByteBuffer wrap = ByteBuffer.wrap("abc".getBytes());
public static ByteBuffer wrap(byte[] array)将一个字节数组包装到缓冲区中。 新的缓冲区将由给定的字节数组支持; 也就是说,对缓冲区的修改将导致数组被修改,反之亦然。 新缓冲区的容量和限制将为array.length ,其位置将为零,其标志将不确定。 其backing array将是给定的数组,其array offset>将为零。 参数 array - 将返回此缓冲区的数组 结果 新的字节缓冲区
5. Buffer 的增查改
增 与 修改
增
ByteBuffer bbf = ByteBuffer.allocate(10); //添加一个字节 bbf.put((byte) '1'); //添加一个字节数组 bbf.put("234".getBytes());
修改 :
ByteBuffer bbf = ByteBuffer.wrap("abcd".getBytes()); byte b = bbf.get(0); System.out.println("b = " + b); bbf.put(0,(byte) 48); b = bbf.get(0); System.out.println("b = " + b);
查
如何查找缓冲区中的内容呢 ? 可以调用 get 方法
一次读一个字节
//切换到读模式 bbf.flip(); //获取缓冲区中的内容 while (bbf.hasRemaining()) { System.out.println("bbf.get() = " +bbf.get()); }
一次读一个字节数组
//切换到读模式 bbf.flip(); //获取缓冲区中的内容 byte[] bytes = new byte[9]; bbf.get(bytes,0,bbf.remaining()); System.out.println(new String(bytes));
6.读与写模式
6.1 flip 读模式
当调用 flip() 方法,切换为读模式时 limit 来到当前 position 的位置 而 position 将回到 起始位置
ByteBuffer bbf = ByteBuffer.allocate(10); for (int i = 0; i < 3; i++) { bbf.put((byte) i); } System.out.println("当前索引 = "+bbf.position()); System.out.println("当前limit = "+bbf.limit()); System.out.println("切换读模式"); bbf.flip(); System.out.println("当前索引 = "+bbf.position()); System.out.println("当前limit = "+bbf.limit());
当前索引 = 3 当前limit = 10 切换读模式 当前索引 = 0 当前limit = 3
调用 rewind() 方法 可将 position 再次移到起始位置 实现重复读
6.2 clear 写模式
当调用 clear() 方法,切换为写模式时 limit 来到当前 capacity 的位置 而 position 将回到 起始位置
此时如果进行添加操作,原值将被覆盖
ByteBuffer bbf = ByteBuffer.allocate(10); for (int i = 0; i < 3; i++) { bbf.put((byte) i); } System.out.println("当前索引 = "+bbf.position()); System.out.println("当前limit = "+bbf.limit()); System.out.println("切换读模式"); bbf.flip(); //切换读模式 System.out.println("当前索引 = "+bbf.position()); System.out.println("当前limit = "+bbf.limit()); while (bbf.hasRemaining()){ System.out.println(bbf.get()); } bbf.clear();//切换写模式 System.out.println("切换写模式"); System.out.println("当前索引 = "+bbf.position()); System.out.println("当前limit = "+bbf.limit()); for (int i = 2; i >=0; i--) { bbf.put((byte) i); } System.out.println("3次添加操作后的索引 = "+bbf.position()); System.out.println("3次添加操作后的limit = "+bbf.limit()); bbf.flip();//再次切换读模式,原值已经被替换 while (bbf.hasRemaining()){ System.out.println(bbf.get()); }
当前索引 = 3 当前limit = 10 切换读模式 当前索引 = 0 当前limit = 3 0 1 2 切换写模式 当前索引 = 0 当前limit = 10 3次添加操作后的索引 = 3 3次添加操作后的limit = 10 2 1 0
7. 总结
capacity:容量 limit: 界限(最多能读/写到哪里)posotion:索引位置
获取缓冲区里面数据之前,需要调用flip方法
再次写数据之前,需要调用clear方法,但是数据还未消失,等再次写入数据,被覆盖了才会消失。