1.属性:
- 容量(capacity):缓冲区能够容纳的数据元素的最大值。这一容量在缓冲区创建时被设定,并且永远不能被改变。
- 上界(limit):缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
- 位置(position):下一个要被读或写的元素的索引。位置会自动由相应的get和put函数更新。
- 标记(mark):一个备忘位置。调用mark()来设定mark=position。调优reset()设定position=mark。标记在设定前是未定义的。 这4个属性之前总是遵循以下关系: 0<=mark<=position<=limit<=capacity 新创建的缓冲区:
2.缓冲区的API:
- capacity():返回缓冲区的容量。
- position():返当前操作指针的位置。
- position(int newposition):设置该缓冲区的position,如果mark被定义并且大于newposition,那么这次设定将被丢弃。
- limit():返回limit的数值。
- limit(int new limit):设置该缓冲区的limit,如果position大于newlimit,那么就设置limit为newlimit,如果mark被定义并且大于newlimit,那么这次设定将被丢弃。
- mark():设置该缓冲区的mark=position。
- reset():重置当前缓冲区的position为之前标记的位置,即令position=mark。
- clear():重置当前缓冲区的属性。
- flip():翻转当前的缓冲区,执行此操作后,将为通道的读写做好准备。
- rewind():将此缓冲区倒回,执行此操作后,将会通道的读做好准备。
- remaining():返回当前位置到limit之前的元素个数。
- hasRemaining():返回是否从当前位置到limit之前有元素。
- nextGetIndex():返回下一个获取的position。 3.压缩:
- compact():该方法的作用主要是将position到limit之间的数据复制到缓冲区的开始位置,如果limit<position,将不会做任何的操作,压缩之后 position=limit-position。limit=capacity。 4.比较:
- 由于ByteBuffer实现了Comparable接口,所以可以通过equals()方法判断两个buffer是否相同。
- 两个缓冲区被认为相同的充要条件是:
- 两个对象类型相同。包含不同数据类型的buffer永远不会相等。
- 两个对象都剩余同样数量的元素。Buffer的容量不需要相同,而且缓冲区中剩余的数据的索引页不必相同。但每个缓冲区剩余元素的数目从位置到上界必须相同。
- 在每个缓冲区中应被get函数返回的剩余元素序列必须一致。 5.创建缓冲区:
- 例如:CharBuffer.allocate(int size):隐含从堆空间分配一个char型数组作为备份存储器来存储char类型的变量。
- 可以使用自己的数组用来做缓冲区的备份存储器:CharBuffer.warp(char[] array)。 6.复制缓冲区:
- duplicate()函数:创建一个与原始缓冲区相似的新缓冲区。两个缓冲区共享数据元素,拥有同样的容量,但每个缓冲区拥有各自的位置,上界和标记属性。对一个缓冲区内元素锁做的改变会反映在另外一个缓冲区上。
-
复制一个缓冲区会创建一个新的Buffer对象,但不会复制数据。原始缓冲区和副本都会操作同样的数据元素。
-
实现原理:
根据当前的备份数组和当前缓冲区的属性重新创建一个缓冲区,缓冲区所使用的备份数组和原缓冲区是共享的,不会重新创建新的数组,也不会申请新的内存。所以任何一个缓冲区改变了数组的数据,另一个缓冲区也会有感知。
-
- asReadOnlyBuffer():生成一个只读的缓冲区视图。这与duplicate相同,除了这个新的缓冲区不允许使用put,并且其isReadOnly函数将会返回true。
- slice():创建一个从原始缓冲区的当前位置开始的新缓冲区,并且其容量是原始缓存区的剩余元素数量。这个新缓冲区与原始缓冲区共享一段数据元素子序列。 7.字节缓冲区:
- 字节顺序:
- 大端字节序:如果数字数值的最高字节,位于低位地址,那么系统就是大端字节顺序。
- 小端字节序:如果最低字节最先保存在内存中,那么就是小端字节顺序。
- 例如:0x12 34 56 78 1)大端模式: 低地址 -----------------> 高地址 0x12 | 0x34 | 0x56 | 0x78 2)小端模式: 低地址 ------------------> 高地址 0x78 | 0x56 | 0x34 | 0x12
- ByteOrder:该类定义了决定从缓冲区中存储或检索多字节数值时使用那一字节顺序的常量。
- 直接缓冲区:
- 直接缓冲区被用于与通道和固有I/O交互,他们通过使用固有代码来告知操作系统直接释放或填充内存区域,对用于通道直接或原始存取的内存区域中的字节元素的存储尽了最大努力。
- 使用非直接缓冲区传递给通道会隐含进行下面的操作:
- 创建一个临时的直接ByteBuffer对象。
- 将非直接缓冲区的内容复制到临时缓冲中。
- 使用临时缓冲区执行低层次I/O操作。
- 临时缓冲区对象离开作用域,并最终成为被回收的无用数据。
- 直接缓冲区比创建非直接缓冲区要花费更高的成本。
- ByteBuffer.allocateDirect():使用此方法来创建一个直接缓冲区。
- isDirect():使用此方法判断该缓冲区是否为直接缓冲区。