ByteBuffer的使用

ByteBuffer

字节缓存区处理子节的,比传统的数组的效率要高。

分类

HeapByteBuffer

用子节数组封装的一种的ByteBuffer,分配在堆上,受GC控制。

DircectByteBuffer

不是分配在堆上,不受GC控制
两者的区别
1,创建和释放DirectByteBuffer的代价要比HeapByteBuffer要高,
2,DirectByteBuffer的读写的操作要比HeapByteBuffer要快

使用

创建

1.获取HeadByteBuffer

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);

其中ByteBuffer.allocate(20);

public static ByteBuffer allocate(int capacity) {
    if (capacity < 0)
        throw new IllegalArgumentException();
    return new HeapByteBuffer(capacity, capacity);
}

HeapByteBuffer(int cap, int lim, boolean isReadOnly) {  
    // package-private
    super(-1, 0, lim, cap, new byte[cap], 0);
    this.isReadOnly = isReadOnly;
}

ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
    super(mark, pos, lim, cap, 0);
    this.hb = hb;
    this.offset = offset;
}

新生成了一个长度为capacity的数组,以及一些标示

2.获取DirectByteBuffer对象

ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(20);

其中ByteBuffer.allocateDirect(20);

public static ByteBuffer allocateDirect(int capacity) {
    if (capacity < 0) {
        throw new IllegalArgumentException("capacity < 0: " + capacity);
    }

    DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
    return new DirectByteBuffer(capacity, memoryRef);
}

MemoryRef(int capacity) {
    VMRuntime runtime = VMRuntime.getRuntime();
    buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
    allocatedAddress = runtime.addressOf(buffer);
    // Offset is set to handle the alignment: http://b/16449607
    offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
    isAccessible = true;
}

由runtime去申请了了一块内存。不是直接在堆内存中。

基本操作

再说基本操作之前,先简单说下的ByteBuffer常见的四个标示
1. position:当前读或者写的位置
2. mark:标记上一次mark的位置,方便reset将postion置为mark的值。
3. limit:标记数据的最大有效的位置
4. capacity:标记buffer的最大可存储值
其中在任意的时候。都必须满足
mark<=position<=limit<=capacity
这里以HeapByteBuffer为例
1.put()
position+1,mark不变,limit 不变,capacity不变

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField(heapByteBuffer);

for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField(heapByteBuffer);

打印的结果

capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
capacity: 20 ,limit: 20 ,position: 10 ,mark: -1

源码

//put
public ByteBuffer put(byte x) {
    if (isReadOnly) {
        throw new ReadOnlyBufferException();
    }
    hb[ix(nextPutIndex())] = x;
    return this;
}

//nextPutIndex
final int nextPutIndex(){
    if(position>=limit){
        throw new BufferOverflowException();
    }
    return position++;
}

2.get()
position++,mark不变,limit不变,capacity不变

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField(heapByteBuffer);

for (int i = 0; i < 10; i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField(heapByteBuffer);

打印结果

capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
0000000000
capacity: 20 ,limit: 20 ,position: 10 ,mark: -1

解释下,初始化,该数组的默认值为0,每次调用get的方法,position+1
源码

public byte get() {
    return hb[ix(nextGetIndex())];
}

3.filp()
limit=position,position=0,capacity不变,mark=-1
模拟一次读写

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);
//写数据
for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.flip();
printField("after flip", heapByteBuffer);
//读数据
for (int i = 0; i < 10; i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get", heapByteBuffer);

打印的结果

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after flip  capacity: 20 ,limit: 10 ,position: 0 ,mark: -1
0123456789
after get  capacity: 20 ,limit: 10 ,position: 10 ,mark: -1

源码

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

4.rewind
position=0,mark =-1,limit 不变,capacity不变

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);
//写操作
for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.rewind();
printField("after rewind", heapByteBuffer);
//读操作
for (int i = 0; i < 10; i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get", heapByteBuffer);

打印

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after rewind  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
0123456789
after get  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1

乍一看似乎和flip的没什么区别。但是我们最大ByteBuffer有效数据是到limit的截止的,这也意味着如果在读写切换操作的时候,你使用rewind的时候,会将一部分脏数据读出来。例如下面的�例子

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);
//写操作
for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.rewind();
printField("after rewind", heapByteBuffer);
//读操作
for (int i = 0; i < heapByteBuffer.limit(); i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get", heapByteBuffer);

打印的结果

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after rewind  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
01234567890000000000
after get  capacity: 20 ,limit: 20 ,position: 20 ,mark: -1

我们会面发现后面10个0并不是我们实现写进去的,但是读的时候却读出来了,如果我们使用flip的操作的时候

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);
//写数据
for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.flip();
printField("after flip", heapByteBuffer);
//读数据
for (int i = 0; i < heapByteBuffer.limit(); i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get", heapByteBuffer);

打印的结果为

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after flip  capacity: 20 ,limit: 10 ,position: 0 ,mark: -1
0123456789
after get  capacity: 20 ,limit: 10 ,position: 10 ,mark: -1

源码

public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}

5.clear()
position=0,mark =-1,capacity不变,limit=capacity

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);
for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.flip();
printField("after flip", heapByteBuffer);

for (int i = 0; i < heapByteBuffer.limit(); i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get", heapByteBuffer);

heapByteBuffer.clear();
printField("after clear",heapByteBuffer);

for (int i = 0; i < heapByteBuffer.limit(); i++) {
    System.out.print(heapByteBuffer.get());
}
System.out.println();
printField("after get",heapByteBuffer);

打印的结果

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after flip  capacity: 20 ,limit: 10 ,position: 0 ,mark: -1
0123456789
after get  capacity: 20 ,limit: 10 ,position: 10 ,mark: -1
after clear  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
01234567890000000000
after get  capacity: 20 ,limit: 20 ,position: 20 ,mark: -1

可以看到并没有影响buffer的数据
源码

public final Buffer clear() {
    position = 0;
    limit = capacity;
    mark = -1;
    return this;
}

6.mark()
7.reset()
mark():mark = position
reset():position = mark;

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);

for (int i = 0; i < 10; i++) {
    heapByteBuffer.put((byte) i);
}
printField("after put", heapByteBuffer);

heapByteBuffer.mark();
printField("after mark", heapByteBuffer);

heapByteBuffer.position(15);
printField("after position", heapByteBuffer);
heapByteBuffer.reset();
printField("after reset", heapByteBuffer);

打印的结果

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after put  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
after mark  capacity: 20 ,limit: 20 ,position: 10 ,mark: 10
after position  capacity: 20 ,limit: 20 ,position: 15 ,mark: 10
after reset  capacity: 20 ,limit: 20 ,position: 10 ,mark: 10

源码

//mark
public final Buffer mark() {
    mark = position;
    return this;
}
//reset
public final Buffer reset() {
    int m = mark;
    if (m < 0)
        throw new InvalidMarkException();
    position = m;
    return this;
}

8.position(int newPosition);
9.limit(int newLimit);
postion(int newPosition):position = newPosition
limit(int newLimit):limit = newLimit;

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);

heapByteBuffer.position(1);
printField("after position", heapByteBuffer);
heapByteBuffer.limit(10);
printField("after limit", heapByteBuffer);

打印的log

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after position  capacity: 20 ,limit: 20 ,position: 1 ,mark: -1
after limit  capacity: 20 ,limit: 10 ,position: 1 ,mark: -1

源码

//position(int newPosition)
public final Buffer position(int newPosition) {
    if ((newPosition > limit) || (newPosition < 0))
        throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
    position = newPosition;
    if (mark > position) mark = -1;
    return this;
}
//limit(int newLimit)
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;
}

10,remaining
11,hasRemaining
remaining:返回剩余的个数
hasRemaining:返回是否还有剩余

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
printField("after create", heapByteBuffer);

System.out.println("remaining:"+heapByteBuffer.remaining());
System.out.println("hasRemaining:"+heapByteBuffer.hasRemaining());

打印的log

after create  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
remaining:20
hasRemaining:true

源码

//remaining
public final int remaining() {
    return limit - position;
}
//hasRemaining
public final boolean hasRemaining() {
    return position < limit;
} 

12,wrap(byte[] byte)
byte变成ByteBuffer: 共用一套的数据,相当于allocate and put,不影响标记量

ByteBuffer wrapByteBuffer = ByteBuffer.wrap(new byte[10]);
printField("after",wrapByteBuffer);

打印log

after  capacity: 10 ,limit: 10 ,position: 0 ,mark: -1

源码

public static ByteBuffer wrap(byte[] array) {
    return wrap(array, 0, array.length);
}
//return HeapByteBuffer
public static ByteBuffer wrap(byte[] array,int offset, int length) {
    try {
        return new HeapByteBuffer(array, offset, length);
    } catch (IllegalArgumentException x) {
        throw new IndexOutOfBoundsException();
    }
}
//array = hb
ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
    super(mark, pos, lim, cap, 0);
    this.hb = hb;
    this.offset = offset;
}

13,put(byte[] byte),将byte的数组放进bytebuffer,相当于byte.length次数往bytebuffer添加byte[index],影响position的位置。

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
byte[] buffer = new byte[]{
        1, 2, 3, 4, 6, 7, 8, 9
    };
heapByteBuffer.put(buffer);
printField("after put",heapByteBuffer);

打印的log

after put  capacity: 20 ,limit: 20 ,position: 8 ,mark: -1

源码

public final ByteBuffer put(byte[] src) {
    return put(src, 0, src.length);
}

public ByteBuffer put(byte[] src, int offset, int length) {
    checkBounds(offset, length, src.length);
    if (length > remaining())
        throw new BufferOverflowException();
    int end = offset + length;
    for (int i = offset; i < end; i++)
        this.put(src[i]);
    return this;
}

14,get(byte[] byte)
取数据,放入到byte数组里面,数组之间不影响,相当于多次的get的操作,影响的position的位置。

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
byte[] buffer = new byte[]{
    1, 2, 3, 4, 6, 7, 8, 9
};
heapByteBuffer.put(buffer);
printField("after put", heapByteBuffer);
heapByteBuffer.rewind();
printField("after rewind", heapByteBuffer);
byte[] outBuffer = new byte[20];
heapByteBuffer.get(outBuffer);
printField("after get", heapByteBuffer);
for(int i = 0;i < outBuffer.length;i++){
    System.out.print(outBuffer[i]);
}

打印的log

after put  capacity: 20 ,limit: 20 ,position: 8 ,mark: -1
after rewind  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after get  capacity: 20 ,limit: 20 ,position: 20 ,mark: -1
12346789000000000000

源码

public ByteBuffer get(byte[] dst) {
    return get(dst, 0, dst.length);
}

public ByteBuffer get(byte[] dst, int offset, int length) {
    checkBounds(offset, length, dst.length);
    if (length > remaining())
        throw new BufferUnderflowException();
    int end = offset + length;
    for (int i = offset; i < end; i++)
        dst[i] = get();
    return this;
}

15,put(int index,byte b)
16,get(int index)
去或者放index位置的值,注意此时不影响position的位置

ByteBuffer heapByteBuffer = ByteBuffer.allocate(20);
heapByteBuffer.put(2, (byte) 2);
printField("after put(index):", heapByteBuffer);
System.out.print(heapByteBuffer.get(2));
printField("after get(index):", heapByteBuffer);

打印的log

after put(index):  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
2
after get(index):  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1

源码分析

//put(int index, byte b);
public ByteBuffer put(int i, byte x) {
    if (isReadOnly) {
        throw new ReadOnlyBufferException();
    }
    //checkIndex() not nextIndex
    hb[ix(checkIndex(i))] = x;
    return this;
}
//get(int index)
public byte get(int i) {
    //chekIndex not nextIndex
    return hb[ix(checkIndex(i))];
}

17,slice
复制有限区域段的byteBuffer,即position到limit的位置。返回的ByteBuffer的position=1,mark=-1,limit=capaticy =src.remaining,并且两个byteBuffer里面的数组相互影响

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
printField("after warp", heapByteBuffer);
//mark = 0
heapByteBuffer.mark();
//position = 5;
heapByteBuffer.position(5);
//limit = 15;
heapByteBuffer.limit(15);
ByteBuffer slice = heapByteBuffer.slice();
printField("after slice", slice);
for (int i = 0; i < slice.limit(); i++) {
    System.out.print(slice.get());
}
System.out.println();
//index = 7,value = 31;
slice.put(7, (byte) 31);
System.out.println(slice.get(7));
System.out.println(heapByteBuffer.get(12));

打印的log

after warp  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
after slice  capacity: 10 ,limit: 10 ,position: 0 ,mark: -1
567891011121314
31
31

源码分析

public ByteBuffer slice() {
    return new HeapByteBuffer(hb,
        -1,
        0,
        remaining(),
        remaining(),
        position() + offset,
        isReadOnly);
}
//-1 = mark 0 = position
//limit = capitity = remaining()
//offset = position()+offset
protected HeapByteBuffer(byte[] buf,int mark, int pos, int lim, int cap,int off, boolean isReadOnly) {
    super(mark, pos, lim, cap, buf, off);
    this.isReadOnly = isReadOnly;
}

18,duplicate
复制的操作,包括所有的标示浮,并且两个ByteBuffer的内存的数组是共同的。

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
printField("after warp", heapByteBuffer);
//mark = 0
heapByteBuffer.mark();
//position = 5;
heapByteBuffer.position(5);
//limit = 15;
heapByteBuffer.limit(15);

ByteBuffer duplicate = heapByteBuffer.duplicate();
printField("heapByteBuffer", heapByteBuffer);
printField("duplicate", duplicate);
duplicate.rewind();
for (int i = 0; i < duplicate.limit(); i++) {
    System.out.print(duplicate.get());
}
System.out.println();
//index = 7,value = 31;
duplicate.put(7, (byte) 31);
System.out.println(duplicate.get(7));
System.out.println(heapByteBuffer.get(7));

打印的log

after warp  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
heapByteBuffer  capacity: 20 ,limit: 15 ,position: 5 ,mark: 0
duplicate  capacity: 20 ,limit: 15 ,position: 5 ,mark: 0
01234567891011121314
31
31

源码分析

//mark = markValue,position= position
//limit = limit(),capacity= capacity()
public ByteBuffer duplicate() {
    return new HeapByteBuffer(hb,
        markValue(),
        position(),
        limit(),
        capacity(),
        offset,
        isReadOnly);
}

19,array
将ByteBuffer转成一个数组,相比get(byte[]b)而言,这两个数组相互影响,但不影响position 的位置。

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
printField("after warp", heapByteBuffer);
//mark = 0
heapByteBuffer.mark();
//position = 5;
heapByteBuffer.position(5);
//limit = 15;
heapByteBuffer.limit(15);

byte[] array = heapByteBuffer.array();
printField("heapByteBuffer", heapByteBuffer);
for (int i = 0; i < array.length; i++) {
    System.out.print(array[i]);
}
System.out.println();
//index = 7,value = 31;
array[7] = 31;
System.out.println(array[7]);
System.out.println(heapByteBuffer.get(7));

打印的log

after warp  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
heapByteBuffer  capacity: 20 ,limit: 15 ,position: 5 ,mark: 0
012345678910111213141516171819
31
31

源码分析

public final byte[] array() {
    if (hb == null)
        throw new UnsupportedOperationException();
    if (isReadOnly)
        throw new ReadOnlyBufferException();
    return hb;
}

20,compact
将positon到limit的内容复制到0~(limit-position)的位置上,并且pisition=limit-position,limit = capatity()

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
printField("after warp", heapByteBuffer);
//mark = 0
heapByteBuffer.mark();
//position = 5;
heapByteBuffer.position(5);
//limit = 15;
heapByteBuffer.limit(15);

ByteBuffer compact = heapByteBuffer.compact();
printField("heapByteBuffer", heapByteBuffer);

heapByteBuffer.rewind();
for (int i = 0; i < heapByteBuffer.limit(); i++) {
    System.out.print(heapByteBuffer.get());
}

打印的log

after warp  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
heapByteBuffer  capacity: 20 ,limit: 20 ,position: 10 ,mark: -1
56789101112131410111213141516171819

源码分析

public ByteBuffer compact() {
    if (isReadOnly) {
        throw new ReadOnlyBufferException();
    }
    // 从position开始复制到remaining位置
    System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
    //postion=remaining();
    position(remaining());
    //limit=capacity()
    limit(capacity());
    discardMark();
    return this;
    }

21.order
22.getInt()/getLong()等
内存中的数据有高序和低序之分的,那么不同的排序,输出的结果也是不同的,同样ByteBuffer中的字节也是有排序的,简称大端和小端排序,通过order来控制数据排序。
我们知道byte占一个子节,int占4个子节,那么就意味着,如果getInt(),则需要byteBuffer中一次取4个子节。这样就能保证取出的是int的数值,

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
heapByteBuffer.order();
printField("order",heapByteBuffer);
System.out.println(heapByteBuffer.getInt());//0123
System.out.println(heapByteBuffer.getInt());//4567
System.out.println(heapByteBuffer.getInt());//891011
System.out.println(heapByteBuffer.getInt());//12131415
System.out.println(heapByteBuffer.getInt());//16171819

打印的log

66051
67438087
134810123
202182159
269554195

解释下:
66051 = 0*256*256*256+1*256*256+2*256+3 //0123
67438087 = 4*256*256*256+5*256*256+6*256+7 //4567
134810123 = 8*256*256*256+9*256*256+10*256+11 //891011

如果将order的顺序改成ByteOrder.LITTLE_ENDIAN
代码如下

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
heapByteBuffer.order(ByteOrder.LITTLE_ENDIAN);
printField("order",heapByteBuffer);
System.out.println(heapByteBuffer.getInt());//3210
System.out.println(heapByteBuffer.getInt());//7654
System.out.println(heapByteBuffer.getInt());//111098
System.out.println(heapByteBuffer.getInt());//15141312
System.out.println(heapByteBuffer.getInt());//19181716

打印的log

order  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
50462976
117835012
185207048
252579084
319951120

解释下:
50462976 = 3*256*256*256+2*256*256+1*256+0;//3210
117835012 = 7*256*256*256+6*256*256+5*256+4;//7654

源码的分析

public int getInt() {
    //position+4
    return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
}

23,asInterBuffer/asLongBuffer
转化成IntBuffer或者其他基本数据的Buffer,并且共享一块数组区域

ByteBuffer heapByteBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
IntBuffer intBuffer = heapByteBuffer.asIntBuffer();
printField("intBuffer", heapByteBuffer);
for (int i = 0; i < intBuffer.limit(); i++) {
    System.out.println(intBuffer.get());
}
intBuffer.put(0,256);
for(int i = 0;i < heapByteBuffer.limit();i++){
    System.out.print(heapByteBuffer.get());
}

打印的log

intBuffer  capacity: 20 ,limit: 20 ,position: 0 ,mark: -1
66051
67438087
134810123
202182159
269554195
001045678910111213141516171819

源码分析

public IntBuffer asIntBuffer() {
    //size/4
    int size = this.remaining() >> 2;
    int off = position();

    //ByteBufferAsIntBuffer 是InterBuffer
    return (IntBuffer) (new ByteBufferAsIntBuffer(this,
        -1,
        0,
        size,
        size,
        off,
        order()));
}

和其他的类常见操作

1,File
创建一个FileChanel

FileChannel fc = new FileInputStream().getChannel();

读数据

fc.read(byteBuffer);
byteBuffer.flip();

写数据

fc.write(byteBuffer);
byteBuffer.clear;
fc.close;

简单的例子 copy的操作

File readFile = new File("bytebuffertest/read.txt");
File outFile = new File("bytebuffertest/write.txt");
try {
    FileChannel readChannel = new FileInputStream(readFile).getChannel();
    ByteBuffer readBuffer = ByteBuffer.allocate(2);
    FileChannel outChannel = new FileOutputStream(outFile).getChannel();
    while (readChannel.read(readBuffer) >= 0) {
        readBuffer.flip();
                System.out.print(Charset.forName("utf-8").decode(readBuffer));
        readBuffer.flip();
        outChannel.write(readBuffer);
        readBuffer.clear();
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

打印log

hello read
i cam come from read.text,want to copy write.txts

同时read.txt的内容转到了write.txt.

2,Socket
创建一个SocketChanel

SocketChanel socketChanel = socket.getChanel();

写数据

 socketChannel.write(buffer);

读数据

 int bytesReaded=socketChannel.read(buffer);

这里就不举例子了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值