注意limit要比mark和position大,比capacity小。
//limit(int)方法的源码 public final Buffer limit(int newLimit) { if ((newLimit > capacity) || (newLimit < 0)) throw new IllegalArgumentException(); limit = newLimit; if (position > limit) position = limit; if (mark > limit) mark = -1; return this; } 标记位置——markmark,就是一个标记为而已,记录当前的position的值。常用的场景,就是记录某一次插入数据的位置,方便下一次进行回溯。
可以使用mark()方法进行标记,
使用reset()方法进行清除,
使用rewind()方法进行初始化
//mark方法标记当前的position,默认为-1 public final Buffer mark() { mark = position; return this; } //reset方法重置mark的位置,position的位置,不能小于mark的位置,否则会出错 public final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; } //重置mark为-1.position为0 public final Buffer rewind() { position = 0; mark = -1; return this; }使用案例
ByteBuffer buffer = ByteBuffer.allocateDirect(1024); buffer.putChar('a'); buffer.putChar('c'); System.out.println("插入完数据 " + buffer); buffer.mark();// 记录mark的位置 buffer.position(30);// 设置的position一定要比mark大,否则mark无法重置 System.out.println("reset前 " + buffer); buffer.reset();// 重置reset ,reset后的position=mark System.out.println("reset后 " + buffer); buffer.rewind();//清除标记,position变成0,mark变成-1 System.out.println("清除标记后 " + buffer);可以看到如下的运行结果:
插入完数据 java.nio.DirectByteBuffer[pos=4 lim=1024 cap=1024] reset前 java.nio.DirectByteBuffer[pos=30 lim=1024 cap=1024] reset后 java.nio.DirectByteBuffer[pos=4 lim=1024 cap=1024] 清除标记后 java.nio.DirectByteBuffer[pos=0 lim=1024 cap=1024] 剩余空间——remaingremaing则表示当前的剩余空间:
public final int remaining() { return limit - position; } 读写实践写操作主要就是按照自己的数据类型,写入到直接内存中,注意每次写入数据的时候,position都会自动加上写入数据的长度,指向下一个该写入的起始位置:
下面看看如何写入一段byte[]或者字符串:
ByteBuffer buffer = ByteBuffer.allocateDirect(10); byte[] data = {1,2}; buffer.put(data); System.out.println("写byte[]后 " + buffer); buffer.clear(); buffer.put("hello".getBytes()); System.out.println("写string后 " + buffer);输出的内容为:
写byte[]后 java.nio.DirectByteBuffer[pos=2 lim=10 cap=10] 写string后 java.nio.DirectByteBuffer[pos=5 lim=10 cap=10]读的时候,可以通过一个外部的byte[]数组进行读取。由于没有找到直接操作直接内存的方法: 因此如果想在JVM应用中使用直接内存,需要申请一段堆中的空间,存放数据。
如果有更好的方法,还请留言。
ByteBuffer buffer = ByteBuffer.allocateDirect(10); buffer.put(new byte[]{1,2,3,4}); System.out.println("刚写完数据 " +buffer); buffer.flip(); System.out.println("flip之后 " +buffer); byte[] target = new byte[buffer.limit()]; buffer.get(target);//自动读取target.length个数据 for(byte b : target){ System.out.println(b); } System.out.println("读取完数组 " +buffer);