您的位置:首页 > Web前端

java.nio.ByteBuffer字节缓冲区源码解析

2018-02-06 15:54 513 查看

1.Buffer的解析

http://blog.csdn.net/ya_1249463314/article/details/79205409

2.所属包

package java.nio;

3.继承与实现关系

public abstract class ByteBuffer
extends Buffer
implements Comparable<ByteBuffer>


4.常用变量

//堆缓冲数组
final byte[] hb;                 //字节数组偏移量
final int offset;
//堆缓冲是否可读
boolean isReadOnly;

5.构造器

/**
* 创建一个带有临时备忘标记变量、读写的开始位置pos、
* 读写的最大容量lim、缓冲区的最大容量cap、字节数组、偏移量的构造器
*/
ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
super(mark, pos, lim, cap);
this.hb = hb;
this.offset = offset;
}

/**
* 创建一个带有临时备忘标记变量mark、读写的开始位置pos、
* 读写的最大容量lim、缓冲区的最大容量cap,字节数组为null,数组偏移量为0的缓冲区
*/
ByteBuffer(int mark, int pos, int lim, int cap) {
this(mark, pos, lim, cap, null, 0);
}

6.常用的方法

/**
* 分配一个新的指定容量的缓冲区
*/
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}

/**
* 分配一个新的指定容量字节缓冲区
*/
public static ByteBuffer allocate(int capacity) {
//如果容量小于0,那么抛出非法参数异常
if (capacity < 0)
throw new IllegalArgumentException();
//返回一个堆字节缓冲区
return new HeapByteBuffer(capacity, capacity);
}

/**
* 封装字节数组到缓冲区中
* 输入参数为字节数组,数组的偏移量,长度
*/
public static ByteBuffer wrap(byte[] array,int offset, int length) {
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}

/**
* 封装字节数组到缓冲区中
*/
public static ByteBuffer wrap(byte[] array) {
return wrap(array, 0, array.length);
}

/**
* 创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。
*/
public abstract ByteBuffer slice();

/**
* 创建共享此缓冲区内容的新的字节缓冲区。
*/
public abstract ByteBuffer duplicate();

/**
* 创建共享此缓冲区内容的新的只读字节缓冲区。
*/
public abstract ByteBuffer asReadOnlyBuffer();

/**
* 读取缓冲区中的字节
*/
public abstract byte get();

/**
* 将给定的字节写入此缓冲区的当前位置,然后该位置递增。
*/
public abstract ByteBuffer put(byte b);

/**
* 从指定的索引处获取字节
*/
public abstract byte get(int index);

/**
* 将给定字节写入此缓冲区的给定索引处。
* index为指定的索引,b为给定的字节
*/
public abstract ByteBuffer put(int index, byte b);

/**
* 将缓冲区中的数据获取复制到输入的字节数组中,赋值的开始偏移量为offset,赋值的长度为length
*/
public ByteBuffer get(byte[] dst, int offset, int length) {
//检查下标是否超出
checkBounds(offset, length, dst.length);
//缓冲区Buffer的剩余元素的数量小于获取的长度,抛出缓冲区溢出错误。
if (length > remaining())
throw new BufferUnderflowException();
//数组的偏移量加上长度为数组尾元素的下标
int end = offset + length;
//从数组的偏移量开始到数组的尾下标处,开始遍历获取元素
for (int i = offset; i < end; i++)
dst[i] = get();
//返回当前的字节缓冲区
return this;
}

/**
* 将缓冲区中的数据获取复制到输入的字节数组中
*/
public ByteBuffer get(byte[] dst) {
return get(dst, 0, dst.length);
}

/**
* 将输入的指定缓冲区中的元素转移到另一个缓冲区中
*/
public ByteBuffer put(ByteBuffer src) {
//如果指定输入的缓冲区就是当前的缓冲区,那么抛出非法参数异常。
if (src == this)
throw new IllegalArgumentException();
//获取输入的缓冲区中存放元素的数量
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
//循环遍历输入缓冲区中的元素将其放到当前的缓冲区中
for (int i = 0; i < n; i++)
put(src.get());
//返回当前的缓冲区
return this;
}

/**
* 将指定的字节数组中的一段数据放到字节缓冲区中
*/
public ByteBuffer put(byte[] src, int offset, int length) {
//检查下标是否超出
checkBounds(offset, length, src.length);
//缓冲区Buffer的剩余元素的数量小于获取的长度,抛出缓冲区溢出错误。
if (length > remaining())
throw new BufferOverflowException();
//输入的字节数组的尾元素的下标
int end = offset + length;
//循环遍历缓冲区中的元素放入到当前的缓冲区中
for (int i = offset; i < end; i++)
this.put(src[i]);
//返回当前的字节缓冲区
return this;
}

/**
* 将指定的字节数组中的数据放到字节缓冲区中
*/
public final ByteBuffer put(byte[] src) {
return put(src, 0, src.length);
}

/**
* 缓冲区是否有一个可访问的字节数组支持
*/
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
}

/**
* 获取字节数组
*/
public final byte[] array() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return hb;
}

/**
* 获取数组的偏移量
*/
public final int arrayOffset() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return offset;
}

public abstract ByteBuffer compact();

/**
* 判断缓冲区是否是直接缓冲区
*/
public abstract boolean isDirect();

/**
* 返回缓冲区的hash值
*/
public int hashCode() {
int h = 1;
int p = position();
for (int i = limit() - 1; i >= p; i--)
h = 31 * h + (int)get(i);
return h;
}

//比较输入的缓冲区中的字节和当前的缓冲区中的字节是否都相同,如果都相同就返回0
public int compareTo(ByteBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
}
return this.remaining() - that.remaining();
}

//比较两个字节
private static int compare(byte x, byte y) {
return Byte.compare(x, y);
}

boolean bigEndian // package-private
= true;
boolean nativeByteOrder // package-private
= (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);

//获取此缓冲区的字节顺序
public final ByteOrder order() {
return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}

//修改此缓冲区的字节顺序
public final ByteBuffer order(ByteOrder bo) {
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
nativeByteOrder =
(bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
return this;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: