目录
HeapByteBuffer与DirectByteBuffer区别
public static ByteBuffer allocate(int capacity):初始化堆缓存
public static ByteBuffer allocateDirect(int capacity):直接内存
ByteBuffer put(byte b);存放byte类型数据
ByteBuffer put(byte[] src):存放byte数组
ByteBuffer put(byte[] src, int offset, int length):从offset(包含)开始截取length长度的数组到ByteBuffer中
public ByteBuffer put(ByteBuffer src):添加一个只读缓存的数据
ByteBuffer put(int index, byte b):将给定的字节写入到这个缓冲区中
ByteBuffer putChar(char value):存放两个字节的char
ByteBuffer putShort(short value);存放两个字节的short
ByteBuffer putChar(int index, char value):在指定的位置插入char
ByteBuffer putShort(int index, short value);在指定位置存放两个字节的short
ByteBuffer putDouble(double value):long和double都是8个字节,添加double和long
ByteBuffer putLong(long value):long和double都是8个字节,添加double和long
putDouble(int index, double value):指定位置添加8个字节的double
ByteBuffer putLong(int index, long value):指定位置添加8个字节的Long
ByteBuffer putFloat(float value);添加四个字节的float
ByteBuffer putInt(int value);添加四个字节的int
ByteBuffer putFloat(int index, float value);指定位置添加四个字节的float
ByteBuffer putInt(int index, int value);指定位置添加四个字节的int
ByteBuffer get(byte[] dst):读取数据到byte[]数组中,并且pos会发生变化
ByteBuffer get(byte[] dst, int offset, int length):从数组offset下标开始(包含),读取length长度缓存到数组demo
byte get(int index);获取缓存位置的值,pos下标不会发生变化
char getChar(int index);读取指定位置两个字节char,pos不会变化
double getDouble();读取8个字节double
double getDouble(int index);读取指定位置8个字节double,pos不会变化
getFloat(int index);读取指定位置四个字节float,pos不会变化
getInt(int index);读取指定位置四个字节的int,pos不会变化
long getLong(int index);读取8个字节的long,pos不会变化
short getShort(int index);读取指定位置两个字节的short,pos不会变化
int arrayOffset():返回给定缓冲区的第一个元素的后备数组内的偏移量(试了几次,返回的总是0)
DoubleBuffer asDoubleBuffer();创建此字节缓冲区作为double缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/8
FloatBuffer asFloatBuffer();创建此字节缓冲区作为float缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/4
IntBuffer asIntBuffer();创建此字节缓冲区作为int缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/4
LongBuffer asLongBuffer();创建此字节缓冲区作为long缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/8
ShortBuffer asShortBuffer();创建此字节缓冲区作为short缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/2
ByteBuffer asReadOnlyBuffer();从原缓存当前位置开始,创建只读缓存
ByteBuffer compact();压缩此缓冲区就是把已经读过的不要了,把剩下的还未读的元素复制到缓存开始的地方
int compareTo(ByteBuffer that) :将此缓冲区剩余的元素与另一个缓冲区剩余元素进行比较。
ByteBuffer duplicate();创建一个共享该缓冲区内容的新字节缓冲区。操作的是同一个数组,所以一个buffer的改变,会影响另一个
boolean isDirect();告知此字节缓冲区是否为直接缓冲区。
ByteOrder order() :检索此缓冲区的字节顺序。
ByteBuffer slice();创建一个新的字节缓冲区,两个缓存共同使用同一个数组和duplicate类似
ByteBuffer wrap(byte[] array):将字节数组包装到缓冲区中。数组长度会作为limit和cap,pos=0,和ByteBuffer原来的值没有关系
ByteBuffer wrap(byte[] array,int offset, int length):将字节数组包装到缓冲区中,只包装从offset开始,length长度
final Buffer clear():清空数据,position、limit、mark还原
Buffer flip():将limit放到position的位置,然后position归0,相当于只读取已经能读取过的缓存
boolean hasRemaining():是否还有可写空间,position<>
int remaining():剩下的limit-position能写的空间
boolean isReadOnly():设置为只读,此时添加数据不会生效
Buffer mark():标记当前position的位置,通过reset能够回到标记
position(int newPosition):设置指针的位置
引入nettyjar包
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.28.Final</version>
</dependency>
ByteBuf API 的优点:
- 它可以被用户自定义的缓冲区类型扩展;
- 通过内置的复合缓冲区类型实现了透明的零拷贝;可以作为一个缓冲区,是因为它是内存中的一段连续的空间
- 容量可以按需增长(类似于JDK 的StringBuilder);
- 在读和写这两种模式之间切换不需要调用ByteBuffer 的flip()方法;
- 读和写使用了不同的索引;
- 支持方法的链式调用;
- 支持引用计数;
- 支持池化。
bytebuffer的四个重要属性
capacity | 当前bytebuffer的总容量,ByteBuffer.allocate(32)表示bytebuffer能存储的字节是32 |
position | 当前读写指针的位置 |
limit | position能够读到limit或者position能够 写到limit |
mark | 用于对position的标记 |
Bytebuffer读和写的转换
ByteBuffer相互转换的Buffer
ByteBuffer常用初始方法(没有构造)
HeapByteBuffer与DirectByteBuffer区别
参考此博客:HeapByteBuffer与DirectByteBuffer - 人在江湖之诗和远方 - 博客园总结
HeapByteBuffer | DirectByteBuffer | |
存储地方和理由 | 在jvm堆上的缓存,底层是一个数组,使用类封装了索引limit,position,capacity | 数据存在操作系统的内存中,而不是jvm,DirectByteBuffer中有一个引用指向操作系统内存中的数据,通过这个引用操作数据 |
优缺点 | 因为是存储在jvm堆当中,所以写速度快,容易回收 | 跟外设(IO)设备交互比较多,因为外设读取jvm堆中的数据时,不是直接读取的,而是把jvm离的数据读到一个操作系统内存块中,再从这个内存块中读取数据。所以使用DirectByteBuffer可以省去这一步,实现传说中的零拷贝 |
题外:外设之所以要把jvm对里的数据copy出来到系统内存里面操作,不是因为操作系统不能直接操作jvm内存,而是因为jvm在进行gc会手的时候,会对数据进行移动,一旦出现这种情况,外设就会出现数据错乱的情况。
public static ByteBuffer allocate(int capacity):初始化堆缓存
demo
public class Test {
public static void main(String[] args) {
ByteBuffer byteBuf = ByteBuffer.allocate(32);
System.out.println(byteBuf);
}
}
结果:
java.nio.HeapByteBuffer[pos=0 lim=32 cap=32]
public static ByteBuffer allocateDirect(int capacity):直接内存
demo
public class Test {
public static void main(String[] args) {
ByteBuffer byteBuf = ByteBuffer.allocateDirect(32);
System.out.println(byteBuf);
}
}
结果
java.nio.DirectByteBuffer[pos=0 lim=32 cap=32]
常用方法
ByteBuffer put(byte b);存放byte类型数据
demo
public class Test {
public static void main(String[] args) {
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
System.out.println(byteBuf);
}
}
ByteBuffer put(byte[] src):存放byte数组
ByteBuffer put(byte[] src, int offset, int length):从offset(包含)开始截取length长度的数组到ByteBuffer中
demo:读取3、4、5到缓存
public class Test {
public static void main(String[] args) {
byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put(b,2,3);
System.out.println(byteBuf.toString());
//切换写为读模式
byteBuf.flip();
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
}
}
结果:
java.nio.HeapByteBuffer[pos=3 lim=32 cap=32]
3
4
5
public ByteBuffer put(ByteBuffer src):添加一个只读缓存的数据
demo:src一定要切换成只读,否则无效(我被这个坑了一个小时,最后才想起来看参数注释)
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(3);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
ByteBuffer byteBuf2 = ByteBuffer.allocate(32);
//这里一定要切换成写模式
byteBuf.flip();
byteBuf2 = byteBuf2.put(byteBuf);
byteBuf2.put((byte)4);
byteBuf2.flip();
System.out.println(byteBuf2.get());
System.out.println(byteBuf2.get());
System.out.println(byteBuf2.get());
System.out.println(byteBuf2.get());
}
}
结果:
1
2
3
4
ByteBuffer put(int index, byte b):将给定的字节写入到这个缓冲区中
demo:已经存放了三个元素,下标是从0开始的,替换3,只能替换已经写入的值,否则会把报错
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(3);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
System.out.println(byteBuf);
//已经存放了三个元素,下标是从0开始的,替换3,只能替换已经写入的值,否则会把报错
byteBuf.put(2,(byte)6);
byteBuf.flip();
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
}
}
结果
java.nio.HeapByteBuffer[pos=3 lim=3 cap=3]
1
2
6
ByteBuffer putChar(char value):存放两个字节的char
ByteBuffer putShort(short value);存放两个字节的short
demo:char和byte区别可以参考:char与byte的区别_喜倾一诺的博客-CSDN博客_char byte
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
//char占两个字节,第一个字节为空,第二个字节为ASCII吗49
byteBuf.putChar('1');
byteBuf.putChar('2');
byteBuf.putChar('3');
System.out.println(byteBuf);
byteBuf.flip();
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.getChar());
System.out.println(byteBuf.getChar());
}
}
结果:一个char是两位字节,所以pos=6
java.nio.HeapByteBuffer[pos=6 lim=32 cap=32]
0
49
2
3
ByteBuffer putChar(int index, char value):在指定的位置插入char
ByteBuffer putShort(int index, short value);在指定位置存放两个字节的short
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
//char占两个字节,第一个字节为空,第二个字节为ASCII吗49
byteBuf.putChar('1');
byteBuf.putChar('2');
byteBuf.putChar('3');
byteBuf.putChar(4,'6');
System.out.println(byteBuf);
byteBuf.flip();
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.getChar());
System.out.println(byteBuf.getChar());
}
}
结果:
java.nio.HeapByteBuffer[pos=6 lim=32 cap=32]
0
49
2
6
ByteBuffer putDouble(double value):long和double都是8个字节,添加double和long
ByteBuffer putLong(long value):long和double都是8个字节,添加double和long
putDouble(int index, double value):指定位置添加8个字节的double
ByteBuffer putLong(int index, long value):指定位置添加8个字节的Long
demo
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
//char占两个字节,第一个字节为空,第二个字节为ASCII吗49
byteBuf.putLong(1L);
byteBuf.putLong(2L);
byteBuf.putDouble(1.02D);
byteBuf.putDouble(2.02D);
System.out.println(byteBuf);
byteBuf.flip();
System.out.println(byteBuf.getLong());
System.out.println(byteBuf.getLong());
System.out.println(byteBuf.getDouble());
System.out.println(byteBuf.getDouble());
}
}
结果:添加了四个8个字节,所以pos=32
java.nio.HeapByteBuffer[pos=32 lim=32 cap=32]
1
2
1.02
2.02
ByteBuffer putFloat(float value);添加四个字节的float
ByteBuffer putInt(int value);添加四个字节的int
ByteBuffer putFloat(int index, float value);指定位置添加四个字节的float
ByteBuffer putInt(int index, int value);指定位置添加四个字节的int
demo:同上putDouble()
get();读取一个字节,pos+1
demo
public class Test {
public static void main(String[] args) {
//byte[] b = new byte[]{ 1,2,3,4,5,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
//char占两个字节,第一个字节为空,第二个字节为ASCII吗49
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
byteBuf.put((byte) 4);
byteBuf.put((byte) 5);
System.out.println(byteBuf);
byteBuf.flip();
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf.get());
System.out.println(byteBuf);
}
}
结果
java.nio.HeapByteBuffer[pos=5 lim=32 cap=32]
flip之后java.nio.HeapByteBuffer[pos=0 lim=5 cap=32]
1
2
3
4
5
java.nio.HeapByteBuffer[pos=5 lim=5 cap=32]
ByteBuffer get(byte[] dst):读取数据到byte[]数组中,并且pos会发生变化
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
byteBuf.put((byte) 4);
byteBuf.put((byte) 5);
System.out.println(byteBuf);
byteBuf.flip();
byteBuf.get(b);
System.out.println("flip之后"+byteBuf);
System.out.println(byteBuf);
System.out.println(Arrays.toString(b));
}
}
结果
java.nio.HeapByteBuffer[pos=5 lim=32 cap=32]
flip之后java.nio.HeapByteBuffer[pos=5 lim=5 cap=32]
java.nio.HeapByteBuffer[pos=5 lim=5 cap=32]
[1, 2, 3, 4, 5]
ByteBuffer get(byte[] dst, int offset, int length):从数组offset下标开始(包含),读取length长度缓存到数组
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
byteBuf.put((byte) 4);
byteBuf.put((byte) 5);
System.out.println(byteBuf);
byteBuf.flip();
byteBuf.get(b,1,2);
System.out.println("flip之后"+byteBuf);
System.out.println(byteBuf);
System.out.println(Arrays.toString(b));
}
}
结果
java.nio.HeapByteBuffer[pos=5 lim=32 cap=32]
flip之后java.nio.HeapByteBuffer[pos=2 lim=5 cap=32]
java.nio.HeapByteBuffer[pos=2 lim=5 cap=32]
[0, 1, 2, 0, 0]
byte get(int index);获取缓存位置的值,pos下标不会发生变化
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
byteBuf.put((byte) 4);
byteBuf.put((byte) 5);
System.out.println(byteBuf);
byteBuf.flip();
//byteBuf.get(b,1,2);
System.out.println("flip之后"+byteBuf);
System.out.println(byteBuf.get(2));
System.out.println("读取之后pos没有发生变化"+byteBuf);
System.out.println(Arrays.toString(b));
}
}
结果
java.nio.HeapByteBuffer[pos=5 lim=32 cap=32]
flip之后java.nio.HeapByteBuffer[pos=0 lim=5 cap=32]
3
java.nio.HeapByteBuffer[pos=0 lim=5 cap=32]
[0, 0, 0, 0, 0]
char getChar();读取两个字节char
char getChar(int index);读取指定位置两个字节char,pos不会变化
double getDouble();读取8个字节double
double getDouble(int index);读取指定位置8个字节double,pos不会变化
float getFloat();读取四个字节float
getFloat(int index);读取指定位置四个字节float,pos不会变化
int getInt();读取四个字节int
getInt(int index);读取指定位置四个字节的int,pos不会变化
long getLong();读取8个字节的long
long getLong(int index);读取8个字节的long,pos不会变化
short getShort();读取两个字节的short
short getShort(int index);读取指定位置两个字节的short,pos不会变化
byte[] array():返回存储数据的数组,bytebuf必须是写模式
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
byteBuf.put((byte) 3);
byteBuf.put((byte) 4);
byteBuf.put((byte) 5);
System.out.println(Arrays.toString(byteBuf.array()));
}
}
结果
[1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
int arrayOffset():返回给定缓冲区的第一个元素的后备数组内的偏移量(试了几次,返回的总是0)
CharBuffer asCharBuffer():创建此字节缓冲区作为char缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/2
demo:
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.putChar('1');
byteBuf.putChar('2');
CharBuffer charBuffer = byteBuf.asCharBuffer();
charBuffer.put('3');
System.out.println(byteBuf);
System.out.println(charBuffer);
byteBuf.flip();
charBuffer.flip();
System.out.println(Arrays.toString(byteBuf.array()));
System.out.println(charBuffer.get());
}
}
结果:新缓冲只有3,而旧的缓存有1,2,3
java.nio.HeapByteBuffer[pos=4 lim=32 cap=32]
[0, 49, 0, 50, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
3
DoubleBuffer asDoubleBuffer();创建此字节缓冲区作为double缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/8
FloatBuffer asFloatBuffer();创建此字节缓冲区作为float缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/4
IntBuffer asIntBuffer();创建此字节缓冲区作为int缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/4
LongBuffer asLongBuffer();创建此字节缓冲区作为long缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/8
ShortBuffer asShortBuffer();创建此字节缓冲区作为short缓冲区的视图镜像,新缓冲区的内容将从该缓冲区的当前位置开始,容量是就缓冲区剩余容量/2
ByteBuffer asReadOnlyBuffer();从原缓存当前位置开始,创建只读缓存
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.putChar('1');
byteBuf.putChar('2');
byteBuf.putChar('2');
byteBuf.flip();
ByteBuffer buffer = byteBuf.asReadOnlyBuffer();
System.out.println(buffer);
System.out.println(buffer.getChar());
}
}
结果
java.nio.HeapByteBufferR[pos=0 lim=6 cap=32]
1
ByteBuffer compact();压缩此缓冲区就是把已经读过的不要了,把剩下的还未读的元素复制到缓存开始的地方
int compareTo(ByteBuffer that) :将此缓冲区剩余的元素与另一个缓冲区剩余元素进行比较。
ByteBuffer duplicate();创建一个共享该缓冲区内容的新字节缓冲区。操作的是同一个数组,所以一个buffer的改变,会影响另一个
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[5];
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte)1);
byteBuf.put((byte)2);
byteBuf.put((byte)3);
byteBuf.put((byte)4);
byteBuf.put((byte)5);
byteBuf.put((byte)6);
byteBuf.put((byte)7);
byteBuf.put((byte)8);
//操作的是同一个数组
ByteBuffer byteBuf2 = byteBuf.duplicate();
System.out.println(Arrays.toString(byteBuf.array()));
System.out.println(Arrays.toString(byteBuf2.array()));
byteBuf.put((byte)9);
byteBuf2.put((byte)10);
System.out.println(Arrays.toString(byteBuf.array()));
System.out.println(Arrays.toString(byteBuf2.array()));
}
}
结果:
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
boolean isDirect();告知此字节缓冲区是否为直接缓冲区。
ByteOrder order() :检索此缓冲区的字节顺序。
ByteBuffer order(ByteOrder bo):修改此缓冲区的字节顺序。(ByteOrder是枚举:包含ByteOrderBIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;)
ByteBuffer slice();创建一个新的字节缓冲区,两个缓存共同使用同一个数组和duplicate类似
ByteBuffer wrap(byte[] array):将字节数组包装到缓冲区中。数组长度会作为limit和cap,pos=0,和ByteBuffer原来的值没有关系
demo
public class Test {
public static void main(String[] args) {
byte[] b = new byte[]{3,4,6};
ByteBuffer byteBuf = ByteBuffer.allocate(32);
byteBuf.put((byte) 1);
byteBuf.put((byte) 2);
ByteBuffer wrap = byteBuf.wrap(b);
System.out.println(Arrays.toString(byteBuf.array()));
System.out.println(Arrays.toString(wrap.array()));
System.out.println(wrap);
System.out.println(Arrays.toString(b));
}
}
结果:
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[3, 4, 6]
java.nio.HeapByteBuffer[pos=0 lim=3 cap=3]
[3, 4, 6]
ByteBuffer wrap(byte[] array,int offset, int length):将字节数组包装到缓冲区中,只包装从offset开始,length长度
Buffer的方法
int capacity():返回总容量
final Buffer clear():清空数据,position、limit、mark还原
Buffer flip():将limit放到position的位置,然后position归0,相当于只读取已经能读取过的缓存
boolean hasRemaining():是否还有可写空间,position<limit
int remaining():剩下的limit-position能写的空间
boolean isReadOnly():设置为只读,此时添加数据不会生效
int limit():元素容量
Buffer mark():标记当前position的位置,通过reset能够回到标记
Buffer reset():回到上一次mark标记的位置
int position():指针的位置
position(int newPosition):设置指针的位置
Buffer rewind():position=0,并清除remark标记