ByteBuffer使⽤实例 ByteBuffer作为JDK的字节流处理对象,这⾥举个⼩例⼦说明下⽤法,直接上代码:package com.wlftytyserver;
import org.junit.Assert;
import org.junit.Test;
import java.nio.ByteBuffer;
public class ByteBufferTest {
@Test
public void byteBufferTest() {
// 写⼊消息体
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
byteBuffer.putInt(0xabef0101);
byteBuffer.putInt(1024); // 今天过节
byteBuffer.put((byte) 1);
byteBuffer.put((byte) 0);
// 读取消息头,因为写完后position已经到10了,所以需要先反转为0,再从头读取
byteBuffer.flip();
printDelimiter(byteBuffer);
// 读取length
printLength(byteBuffer);
// 继续读取剩下数据
<();
<();
printByteBuffer(byteBuffer);
/
/ 我再反转⼀下,我还可以从头开始读
byteBuffer.flip();
printDelimiter(byteBuffer);
// clear清空⼀下,再从头开始读
byteBuffer.clear();
printDelimiter(byteBuffer);
// rewind重绕⼀下
printDelimiter(byteBuffer);
// mark标记⼀下
byteBuffer.mark();
/
/ 再读取length
printLength(byteBuffer);
// reset重置,回到读取delimiter的地⽅
printByteBuffer(byteBuffer);
}
private void printDelimiter(ByteBuffer buf) {
int newDelimiter = Int();
System.out.printf("delimeter: %s\n", HexString(newDelimiter));
printByteBuffer(buf);
}
private void printLength(ByteBuffer buf) {
int length = Int();
System.out.printf("length: %d\n", length);
printByteBuffer(buf);
}
private void printByteBuffer(ByteBuffer buf) {
System.out.printf("position: %d, limit: %d, capacity: %d\n", buf.position(), buf.limit(), buf.capacity());
}
}
输出结果:
delimeter: abef0101
position: 4, limit: 10, capacity: 10
length: 1024
position: 8, limit: 10, capacity: 10
position: 10, limit: 10, capacity: 10
delimeter: abef0101
position: 4, limit: 10, capacity: 10
delimeter: abef0101
position: 4, limit: 10, capacity: 10
delimeter: abef0101
position: 4, limit: 10, capacity: 10
length: 1024
position: 8, limit: 10, capacity: 10
position: 4, limit: 10, capacity: 10
Process finished with exit code 0
ByteBuffer的索引是唯⼀的。像上⾯的例⼦,初始索引是0,写完索引值为9,为了读取写⼊的值,我们再重新设置索引为0(调⽤flip⽅法)。ByteBuffer有4个索引值,分别是:jdk怎么使用
mask:就是你标记的索引,标记唯⼀的作⽤是调⽤reset重置回到过去
position:当前位置的索引,mask标记任何时候都不会⼤于position,因为你必须先读到当前位置之后,才能标记该位置;同时position 也不能超过limit限制
limit:第⼀个不应该读取或写⼊的元素的索引,也就是读写禁地,默认是最⼤容量,如果你设置该值,那么理所让然它不能超过最⼤容量capacity
capacity:这个就不解释了
它们的⼤⼩关系始终是:
mask <= position <= limit <= capacity
我们上⾯的例⼦中就是capacity=limit。
初始索引:
+-----------------------------------------------------+
/ bytes /
+-----------------------------------------------------+
/ 10 /
0=position 10=limit=capacity
我们写⼊delimiter之后:
+----------------+------------------------------------+
/ delimiter / other bytes /
+----------------+------------------------------------+
/ 4 / 6 /
0 4=position 10=limit=capacity
⾄于反转flip如何切换读写模式、reset如何重置标记、clear清除如何重新设置索引值为0、rewind重绕如何让你重新读取,都不会动内容,所以你会看到上⾯不管怎么折腾我们都可以重复取出delimiter、length的值。看下源码就⼀清⼆楚了,⽆⾮就是对上⾯4个索引值进⾏赋值⽽已:
/**
* Resets this buffer's position to the previously-marked position.
*
* <p> Invoking this method neither changes nor discards the mark's
* value. </p>
*
* @return This buffer
*
* @throws InvalidMarkException
* If the mark has not been set
*/
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
/**
* Clears this buffer. The position is set to zero, the limit is set to
* the capacity, and the mark is discarded.
*
* <p> Invoke this method before using a sequence of channel-read or
* <i>put</i> operations to fill this buffer. For example:
*
* <blockquote><pre>
* buf.clear(); // Prepare buffer for reading
* in.read(buf); // Read data</pre></blockquote>
*
* <p> This method does not actually erase the data in the buffer, but it
* is named as if it did because it will most often be used in situations
* in which that might as well be the case. </p>
*
* @return This buffer
*/
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
/**
* Flips this buffer. The limit is set to the current position and then
* the position is set to zero. If the mark is defined then it is
* discarded.
*
* <p> After a sequence of channel-read or <i>put</i> operations, invoke
* this method to prepare for a sequence of channel-write or relative
* <i>get</i> operations. For example:
*
* <blockquote><pre>
* buf.put(magic); // Prepend header
* in.read(buf); // Read data into rest of buffer
* buf.flip(); // Flip buffer
* out.write(buf); // Write header + data to channel</pre></blockquote>
*
* <p> This method is often used in conjunction with the {@link
* java.nio.ByteBuffer#compact compact} method when transferring data from * one place to another. </p>
*
* @return This buffer
*/
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
/**
* Rewinds this buffer. The position is set to zero and the mark is
* discarded.
*
* <p> Invoke this method before a sequence of channel-write or <i>get</i> * operations, assuming that the limit has already been set
* appropriately. For example:
*
* <blockquote><pre>
* out.write(buf); // Write remaining data
* wind(); // Rewind buffer
* (array); // Copy data into array</pre></blockquote>
*
* @return This buffer
*/
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论