使用ByteBuffer

文章目录

    • 创建堆缓冲区和直接缓冲区
    • 直接缓冲区与非直接缓冲区运行效率比较
    • 包装wrap数据的处理
    • put(byte[] b)和get()方法的使用
    • put(byte[] src, int offset, int length)和get(byte[] dst, int offset, int length)
    • put(ByteBuffer src)
    • putType()和getType()
    • slice()方法
    • 转换为CharBuffer字符缓冲区及中文的处理
    • 设置与获得字节顺序
    • 创建只读缓冲区
    • 压缩缓冲区
    • 比较缓冲区内容
    • 复制缓冲区
    • 对缓冲区扩容

ByteBuffer类提供了6类操作。

  1. 以绝对位置和相对位置读写单个字节的get()和put()方法
  2. 使用相对批量get(byte[] dst)方法可以将缓冲区中的连续字节传输到byte[] dst目标数组中。
  3. 使用相对批量put(byte[] src)方法可以将byte[]数组或其他字节缓冲区中的连续字节存储到此缓冲区中。
  4. 使用相对和绝对getType和putType方法可以按照字节顺序在字节序列中读写其他基本数据类型的值,方法getType和putType可以进行数据类型的自动转换。
  5. 提供了创建视图缓冲区的方法,这些方法允许将字节缓冲区视为包含其他基本类型值的缓冲区,这些方法有asCharBuffer()、asDoubleBuffer()、asFloatBuffer()、asIntBuffer()、asLongBuffer()、asShortBuffer()。
  6. 提供了对字节缓冲区进行压缩(compacting)、复制(duplicating)和截取(slicing)的方法。

创建堆缓冲区和直接缓冲区

字节缓冲区分为直接字节缓冲区(JVM会尽量直接对内核空间进行IO操作,避免将缓冲区内容复制到中间缓冲区,提高效率)和非直接字节缓冲区。
allocateDirect()创建直接字节缓冲区,通过工厂方法allocateDirect()返回的缓冲区进行内存的分配和释放所需要的时间成本通常要高于非直接缓冲区。

allocate源码:

/**
     * Allocates a new direct byte buffer.
     *
     * 

The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be * initialized to zero. Whether or not it has a * {@link #hasArray backing array} is unspecified. * * @param capacity * The new buffer's capacity, in bytes * * @return The new byte buffer * * @throws IllegalArgumentException * If the capacity is a negative integer */ public static ByteBuffer allocateDirect(int capacity) { return new DirectByteBuffer(capacity); } /** * Allocates a new byte buffer. * *

The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be * initialized to zero. It will have a {@link #array backing array}, * and its {@link #arrayOffset array offset} will be zero. * * @param capacity * The new buffer's capacity, in bytes * * @return The new byte buffer * * @throws IllegalArgumentException * If the capacity is a negative integer */ public static ByteBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapByteBuffer(capacity, capacity); }

直接缓冲区与非直接缓冲区运行效率比较

long begin = System.currentTimeMillis();
ByteBuffer buffer = ByteBuffer.allocateDirect(1000000000);
for (int i = 0; i < 1000000000; i++) {
    buffer.put((byte)100);
}
System.out.println(System.currentTimeMillis() - begin);

output:
	1896
long begin = System.currentTimeMillis();
ByteBuffer buffer = ByteBuffer.allocate(1000000000);
 for (int i = 0; i < 1000000000; i++) {
     buffer.put((byte)100);
 }
 System.out.println(System.currentTimeMillis() - begin);

output:
	2575

直接缓冲区运行效率要高些。直接缓冲区(DIrectByteBuffer)内部使用sun.misc.Unsafe类进行值的处理。Unsafe的作用是JVM与操作系统进行直接通信,提高程序运行的效率。

public ByteBuffer put(byte x) {
        unsafe.putByte(ix(nextPutIndex()), ((x)));
        return this;
}

非直接缓冲区(HeapByteBuffer)在内部直接对byte[] hb字节数组进行操作,而且还是在JVM的堆中进行数据处理,运行效率相对慢些。

public ByteBuffer put(byte x) {
        hb[ix(nextPutIndex())] = x;
        return this;
 }

包装wrap数据的处理

wrap(byte[] array):

/**
     * Wraps a byte array into a buffer.
     *
     * 

The new buffer will be backed by the given byte array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity and limit will be * array.length, its position will be zero, and its mark will be * undefined. Its {@link #array backing array} will be the * given array, and its {@link #arrayOffset array offset>} will * be zero.

* * @param array * The array that will back this buffer * * @return The new byte buffer */ public static ByteBuffer wrap(byte[] array) { return wrap(array, 0, array.length); }

wrap(byte[] array, int offset, int length):

 /**
     * Wraps a byte array into a buffer.
     *
     * 

The new buffer will be backed by the given byte array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity will be * array.length, its position will be offset, its limit * will be offset + length, and its mark will be undefined. Its * {@link #array backing array} will be the given array, and * its {@link #arrayOffset array offset} will be zero.

* * @param array * The array that will back the new buffer * * @param offset * The offset of the subarray to be used; must be non-negative and * no larger than array.length. The new buffer's position * will be set to this value. * * @param length * The length of the subarray to be used; * must be non-negative and no larger than * array.length - offset. * The new buffer's limit will be set to offset + length. * * @return The new byte buffer * * @throws IndexOutOfBoundsException * If the preconditions on the offset and length * parameters do not hold */ public static ByteBuffer wrap(byte[] array, int offset, int length) { try { return new HeapByteBuffer(array, offset, length); } catch (IllegalArgumentException x) { throw new IndexOutOfBoundsException(); } }

注意:wrap(byte[] array, int offset, int length)参数offset只是设置缓冲区的position值,length确定limit值

Demo:

byte[] byteArr = new byte[]{1,2,3,4,5,6,7,8};
ByteBuffer byteBuffer1 = ByteBuffer.wrap(byteArr);
ByteBuffer byteBuffer2 = ByteBuffer.wrap(byteArr,2,4);
System.out.println("bytebuffer1 capacity=" + byteBuffer1.capacity() + " limit=" + byteBuffer1.limit() + " position=" + byteBuffer1.position());
System.out.println("bytebuffer2 capacity=" + byteBuffer2.capacity() + " limit=" + byteBuffer2.limit() + " position=" + byteBuffer2.position());

output:
	bytebuffer1 capacity=8 limit=8 position=0
	bytebuffer2 capacity=8 limit=6 position=2

put(byte[] b)和get()方法的使用

get和put分别提供两种操作,相对位置和绝对位置操作。执行相对位置读或者写操作后,position递增

/**
     * Relative get method.  Reads the byte at this buffer's
     * current position, and then increments the position.
     *
     * @return  The byte at the buffer's current position
     *
     * @throws  BufferUnderflowException
     *          If the buffer's current position is not smaller than its limit
     */
    public abstract byte get();

    /**
     * Relative put method  (optional operation).
     *
     * 

Writes the given byte into this buffer at the current * position, and then increments the position.

* * @param b * The byte to be written * * @return This buffer * * @throws BufferOverflowException * If this buffer's current position is not smaller than its limit * * @throws ReadOnlyBufferException * If this buffer is read-only */ public abstract ByteBuffer put(byte b); /** * Absolute get method. Reads the byte at the given * index. * * @param index * The index from which the byte will be read * * @return The byte at the given index * * @throws IndexOutOfBoundsException * If index is negative * or not smaller than the buffer's limit */ public abstract byte get(int index); /** * Absolute put method  (optional operation). * *

Writes the given byte into this buffer at the given * index.

* * @param index * The index at which the byte will be written * * @param b * The byte value to be written * * @return This buffer * * @throws IndexOutOfBoundsException * If index is negative * or not smaller than the buffer's limit * * @throws ReadOnlyBufferException * If this buffer is read-only */ public abstract ByteBuffer put(int index, byte b);

put(byte[] src, int offset, int length)和get(byte[] dst, int offset, int length)

相对批量put方法,将给定源数组中的字节传输到此缓冲区当前位置中。

/**
     * Relative bulk put method  (optional operation).
     *
     * 

This method transfers bytes into this buffer from the given * source array. If there are more bytes to be copied from the array * than remain in this buffer, that is, if * length > remaining(), then no * bytes are transferred and a {@link BufferOverflowException} is * thrown. * *

Otherwise, this method copies length bytes from the * given array into this buffer, starting at the given offset in the array * and at the current position of this buffer. The position of this buffer * is then incremented by length. * *

In other words, an invocation of this method of the form * dst.put(src, off, len) has exactly the same effect as * the loop * *

{@code
     *     for (int i = off; i < off + len; i++)
     *         dst.put(a[i]);
     * }
* * except that it first checks that there is sufficient space in this * buffer and it is potentially much more efficient. * * @param src * The array from which bytes are to be read * * @param offset * The offset within the array of the first byte to be read; * must be non-negative and no larger than array.length * * @param length * The number of bytes to be read from the given array; * must be non-negative and no larger than * array.length - offset * * @return This buffer * * @throws BufferOverflowException * If there is insufficient space in this buffer * * @throws IndexOutOfBoundsException * If the preconditions on the offset and length * parameters do not hold * * @throws ReadOnlyBufferException * If this buffer is read-only */ 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; }

dst.put(src,offset,length)等同于下面的循环语句

for(int i = offset;i < offset + length;i++){
	dst.put(a[i])
}

相对批量get方法,将缓冲区当前位置的字节传输到给定的目标数组中。

 // -- Bulk get operations --

    /**
     * Relative bulk get method.
     *
     * 

This method transfers bytes from this buffer into the given * destination array. If there are fewer bytes remaining in the * buffer than are required to satisfy the request, that is, if * length > remaining(), then no * bytes are transferred and a {@link BufferUnderflowException} is * thrown. * *

Otherwise, this method copies length bytes from this * buffer into the given array, starting at the current position of this * buffer and at the given offset in the array. The position of this * buffer is then incremented by length. * *

In other words, an invocation of this method of the form * src.get(dst, off, len) has exactly the same effect as * the loop * *

{@code
     *     for (int i = off; i < off + len; i++)
     *         dst[i] = src.get():
     * }
* * except that it first checks that there are sufficient bytes in * this buffer and it is potentially much more efficient. * * @param dst * The array into which bytes are to be written * * @param offset * The offset within the array of the first byte to be * written; must be non-negative and no larger than * dst.length * * @param length * The maximum number of bytes to be written to the given * array; must be non-negative and no larger than * dst.length - offset * * @return This buffer * * @throws BufferUnderflowException * If there are fewer than length bytes * remaining in this buffer * * @throws IndexOutOfBoundsException * If the preconditions on the offset and length * parameters do not hold */ 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; }

Demo:

		byte[] byteArr1 = new byte[]{1,2,3,4,5,6,7,8};
        byte[] byteArr2 = new byte[]{55,66,77,88};
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        byteBuffer.put(byteArr1);
        byteBuffer.position(2);
        byteBuffer.put(byteArr2,1,3);

        byte[] getByte = byteBuffer.array();
        for (int i = 0; i < getByte.length; i++) {
            System.out.print(getByte[i] + " ");
        }
        System.out.println();
        byteBuffer.position(1);
        byte[] byteArrOut = new byte[byteBuffer.capacity()];
        byteBuffer.get(byteArrOut,3,4);
        for (int i = 0; i < byteArrOut.length; i++) {
            System.out.print(byteArrOut[i] + " ");
        }
        System.out.println();

output:
	1 2 66 77 88 6 7 8 0 0 
	0 0 0 2 66 77 88 0 0 0 

put(ByteBuffer src)

相对批量put方法,将给定源缓冲区的剩余字节传输到此缓冲区的当前位置。

 // -- Bulk put operations --

    /**
     * Relative bulk put method  (optional operation).
     *
     * 

This method transfers the bytes remaining in the given source * buffer into this buffer. If there are more bytes remaining in the * source buffer than in this buffer, that is, if * src.remaining() > remaining(), * then no bytes are transferred and a {@link * BufferOverflowException} is thrown. * *

Otherwise, this method copies * n = src.remaining() bytes from the given * buffer into this buffer, starting at each buffer's current position. * The positions of both buffers are then incremented by n. * *

In other words, an invocation of this method of the form * dst.put(src) has exactly the same effect as the loop * *

     *     while (src.hasRemaining())
     *         dst.put(src.get()); 
* * except that it first checks that there is sufficient space in this * buffer and it is potentially much more efficient. * * @param src * The source buffer from which bytes are to be read; * must not be this buffer * * @return This buffer * * @throws BufferOverflowException * If there is insufficient space in this buffer * for the remaining bytes in the source buffer * * @throws IllegalArgumentException * If the source buffer is this buffer * * @throws ReadOnlyBufferException * If this buffer is read-only */ public ByteBuffer put(ByteBuffer src) { if (src == this) throw new IllegalArgumentException(); if (isReadOnly()) throw new ReadOnlyBufferException(); int n = src.remaining(); if (n > remaining()) throw new BufferOverflowException(); for (int i = 0; i < n; i++) put(src.get()); return this; }

Demo

		byte[] byteArr1 = new byte[]{1,2,3,4,5,6,7,8};
        ByteBuffer buffer1 = ByteBuffer.wrap(byteArr1);

        byte[] byteArr2 = new byte[]{55,66,77,88};
        ByteBuffer buffer2 = ByteBuffer.wrap(byteArr2);

        buffer1.position(4);
        buffer2.position(1);

        buffer1.put(buffer2);

        System.out.println(buffer1.position());
        System.out.println(buffer2.position());

        byte[] byteArrOut = buffer1.array();
        for (int i = 0; i < byteArrOut.length; i++) {
            System.out.print(byteArrOut[i] + " ");
        }
        System.out.println();
    
  output:
  		7
		4
		1 2 3 4 66 77 88 8 

putType()和getType()

putChar(char value)

 /**
     * Relative put method for writing a char
     * value  (optional operation).
     *
     * 

Writes two bytes containing the given char value, in the * current byte order, into this buffer at the current position, and then * increments the position by two.

* * @param value * The char value to be written * * @return This buffer * * @throws BufferOverflowException * If there are fewer than two bytes * remaining in this buffer * * @throws ReadOnlyBufferException * If this buffer is read-only */ public abstract ByteBuffer putChar(char value);

putChar(int index, char value)
putDouble(double value) //8个字节
putDouble(int index, double value)
putFloat(float value) //4个字节
putFloat(int index, float value)
putInt(int value) //4个字节
putInt(int index, int value)
putLong(long value) //8个字节
putLong(int index, int value)
putShort(short value) //2个字节
putShort(int index, short value)

slice()方法

创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。新缓冲区的内容将从此缓冲区的当前位置开始。此缓冲区内容的更改子新缓冲区是可见的,反之亦然;两个缓冲区的位置、限制和标记值是相互独立的。新缓冲区的位置将为0,其容量和限制将为此缓冲区中所剩余的字节数量,标记是不确定的

 /**
     * Creates a new byte buffer whose content is a shared subsequence of
     * this buffer's content.
     *
     * 

The content of the new buffer will start at this buffer's current * position. Changes to this buffer's content will be visible in the new * buffer, and vice versa; the two buffers' position, limit, and mark * values will be independent. * *

The new buffer's position will be zero, its capacity and its limit * will be the number of bytes remaining in this buffer, and its mark * will be undefined. The new buffer will be direct if, and only if, this * buffer is direct, and it will be read-only if, and only if, this buffer * is read-only.

* * @return The new byte buffer */ public abstract ByteBuffer slice();

Demo

 		byte[] byteArr1 = new byte[]{1,2,3,4,5,6,7,8};
        ByteBuffer buffer1 = ByteBuffer.wrap(byteArr1);

        buffer1.position(4);
        ByteBuffer buffer2 = buffer1.slice();
        System.out.println("buffer1 position=" + buffer1.position() + " capacity=" + buffer1.capacity() + " limit=" + buffer1.limit());
        System.out.println("buffer2 position=" + buffer2.position() + " capacity=" + buffer2.capacity() + " limit=" + buffer2.limit());

        buffer2.put(0,(byte)100);
        byte[] byteArrOut1 = buffer1.array();
        for (int i = 0; i < byteArrOut1.length; i++) {
            System.out.print(byteArrOut1[i] + " ");
        }
        System.out.println();
        byte[] byteArrOut2 = buffer1.array();
        for (int i = 0; i < byteArrOut2.length; i++) {
            System.out.print(byteArrOut2[i] + " ");
        }
        System.out.println();

output:
	buffer1 position=4 capacity=8 limit=8
	buffer2 position=0 capacity=4 limit=4
	1 2 3 4 100 6 7 8 
	1 2 3 4 100 6 7 8 

转换为CharBuffer字符缓冲区及中文的处理

asCharBuffer

/**
     * Creates a view of this byte buffer as a char buffer.
     *
     * 

The content of the new buffer will start at this buffer's current * position. Changes to this buffer's content will be visible in the new * buffer, and vice versa; the two buffers' position, limit, and mark * values will be independent. * *

The new buffer's position will be zero, its capacity and its limit * will be the number of bytes remaining in this buffer divided by * two, and its mark will be undefined. The new buffer will be direct * if, and only if, this buffer is direct, and it will be read-only if, and * only if, this buffer is read-only.

* * @return A new char buffer */ public abstract CharBuffer asCharBuffer();

Demo

		byte[] byteArr1 = "我是好学生".getBytes();
        System.out.println(Charset.defaultCharset().name());

        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArr1);
        System.out.println(byteBuffer.getClass().getName());

        CharBuffer charBuffer = byteBuffer.asCharBuffer();
        System.out.println(charBuffer.getClass().getName());

        System.out.println("byteBuffer position=" + byteBuffer.position() + " capacity=" + byteBuffer.capacity() + " limit=" + byteBuffer.limit());
        System.out.println("charBuffer position=" + charBuffer.position() + " capacity=" + charBuffer.capacity() + " limit=" + charBuffer.limit());

        charBuffer.position(0);
        for (int i = 0; i < charBuffer.capacity(); i++) {
            System.out.print(charBuffer.get() + " ");
        }
        System.out.println();
        
output:
	UTF-8
	java.nio.HeapByteBuffer
	java.nio.ByteBufferAsCharBufferB	
	byteBuffer position=0 capacity=15 limit=15
	charBuffer position=0 capacity=7 limit=7
	 釦 颯  뷥 궦  

出现了乱码。
byteArr1数组中存储的编码为UTF-8,wrap后,缓冲区存储的编码也为UTF-8,asCharBuffer后,UTF-8编码的ByteBuffer转换成UTF-8的CharBuffer,在调用charBuffer的get方法时,以UTF-16BE的编码格式获得中文时出现编码不匹配的情况,出现了乱码

解决方法1:
将中文按utf-16be编码转化成字节数组

byte[] byteArr1 = "我是好学生".getBytes("utf-16BE");

解决方法2:

byte[] byteArr1 = "我是好学生".getBytes("utf-8");
……
CharBuffer charBuffer = Charset.forName("utf-8").decode(byteBuffer)
……

设置与获得字节顺序

order()方法与字节数据排列的顺序有关,不同的CPU在读取字节时的顺序是不一样的,有的CPU从高位开始读,有的CPU从低位开始读,order(ByteOrder bo)设置字节的排列顺序。
ByteOrder order()方法的作用:获取此缓冲区的字节顺序。新创建的字节缓冲区的顺序始终为BIG_ENDIAN。
1):public static final ByteOrder BIG_ENDIAN:表示BIG_ENDIAN字节顺序的常量。按照此顺序,多字节值的字节顺序是从最高有效位到最低有效位的。
2):public static final ByteOrder LITTLE_ENDIAN:表示LITTLE_ENDIAN字节顺序的常量。按照此顺序,多字节值的字节顺序是从最低有效位到最高有效位的。
order(ByteOrder bo):修改此缓冲区的字节顺序,默认情况下,字节缓冲区的初始顺序是BIG_ENDIAN。

创建只读缓冲区

asReadOnlyBuffer():创建共享此缓冲区内容的新的只读字节缓冲区。新缓冲区的内容将为此缓冲区的内容。此缓冲区内容的更改在新缓冲区可见,新缓冲区内容是只读的

		byte[] byteArrIn = {1,2,3,4,5};
        ByteBuffer buffer1 = ByteBuffer.wrap(byteArrIn);
        ByteBuffer buffer2 = buffer1.asReadOnlyBuffer();
        System.out.println(buffer1.isReadOnly());
        System.out.println(buffer2.isReadOnly());
        buffer2.rewind();
        buffer2.put((byte)111);

output:
	false
	true
	java.nio.ReadOnlyBufferException
		at java.nio.HeapByteBufferR.put(HeapByteBufferR.java:172)

压缩缓冲区

compact:将缓冲区的当前位置和限制之间的字节复制到缓冲区的开始处,即将索引p=position()处的字节复制到索引0处,将索引p+1处的字节复制到索引1处,依此类推,直到将索引limit()-1处的自己复制到索引n = limit() - 1 -p处。然后,将缓冲区的的位置设置为n+1,并将其限制设置为其容量。

/**
     * Compacts this buffer  (optional operation).
     *
     * 

The bytes between the buffer's current position and its limit, * if any, are copied to the beginning of the buffer. That is, the * byte at index p = position() is copied * to index zero, the byte at index p + 1 is copied * to index one, and so forth until the byte at index * limit() - 1 is copied to index * n = limit() - 1 - p. * The buffer's position is then set to n+1 and its limit is set to * its capacity. The mark, if defined, is discarded. * *

The buffer's position is set to the number of bytes copied, * rather than to zero, so that an invocation of this method can be * followed immediately by an invocation of another relative put * method.

* * *

Invoke this method after writing data from a buffer in case the * write was incomplete. The following loop, for example, copies bytes * from one channel to another via the buffer buf: * *

{@code
     *   buf.clear();          // Prepare buffer for use
     *   while (in.read(buf) >= 0 || buf.position != 0) {
     *       buf.flip();
     *       out.write(buf);
     *       buf.compact();    // In case of partial write
     *   }
     * }
* * * @return This buffer * * @throws ReadOnlyBufferException * If this buffer is read-only */ public abstract ByteBuffer compact();

比较缓冲区内容

方法一:
equals:

/**
     * Tells whether or not this buffer is equal to another object.
     * 

Two byte buffers are equal if, and only if, *

    *
  1. They have the same element type,

  2. *
  3. They have the same number of remaining elements, and *

  4. *
  5. The two sequences of remaining elements, considered * independently of their starting positions, are pointwise equal. *

    A byte buffer is not equal to any other type of object.

    * @param ob The object to which this buffer is to be compared * * @return true if, and only if, this buffer is equal to the * given object */ public boolean equals(Object ob) { if (this == ob) return true; if (!(ob instanceof ByteBuffer)) return false; ByteBuffer that = (ByteBuffer)ob; if (this.remaining() != that.remaining()) return false; int p = this.position(); for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) if (!equals(this.get(i), that.get(j))) return false; return true; }
  1. 判断是否是自身,如果是自身,返回true
  2. 判断是不是ByteBuffer类的实例,如果不是,返回false;
  3. 判断remaining是否一样,不一样,返回false;
  4. 判断position和limit是否一样,有一个不一样,返回false。

从源码看,两个缓冲区的capacity可以不一样。

方法二:
compareTo

 /**
     * Compares this buffer to another.
     *
     * 

Two byte buffers are compared by comparing their sequences of * remaining elements lexicographically, without regard to the starting * position of each sequence within its corresponding buffer. * Pairs of {@code byte} elements are compared as if by invoking * {@link Byte#compare(byte,byte)}. *

A byte buffer is not comparable to any other type of object. * * @return A negative integer, zero, or a positive integer as this buffer * is less than, equal to, or greater than the given buffer */ 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(); }

1)判断两个ByteBuffer的范围是从当前ByteBuffer对象的当前位置开始,以两个ByteBuffer对象最小的remaining结束,说明判断的范围是remaining交集
2) 如果在开始和结束的范围之间有一个字节不同,则返回两者的减数
3) 如果在开始和结束的范围之间每个字节都相同,则返回两者remaining的减数

复制缓冲区

 /**
     * Creates a new byte buffer that shares this buffer's content.
     *
     * 

The content of the new buffer will be that of this buffer. Changes * to this buffer's content will be visible in the new buffer, and vice * versa; the two buffers' position, limit, and mark values will be * independent. * *

The new buffer's capacity, limit, position, and mark values will be * identical to those of this buffer. The new buffer will be direct if, * and only if, this buffer is direct, and it will be read-only if, and * only if, this buffer is read-only.

* * @return The new byte buffer */ public abstract ByteBuffer duplicate();

对缓冲区扩容

 public static ByteBuffer extendsSize(ByteBuffer byteBuffer,int extendSize){
        ByteBuffer newByteBuffer = ByteBuffer.allocate(byteBuffer.capacity() + extendSize);
        newByteBuffer.put(byteBuffer);
        return newByteBuffer;
    }

你可能感兴趣的:(#,NIO与Socket编程)