Cited examples
Take an example to illustrate the differences of these methods in ByteBuffer in combination with graphics
public class ByteBufferDemo { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); //8 bytes are required to store Double here. If the ByteBuffer space is less than 8 bytes, an error bufferoverflow exception will be reported byte[] bytes=new byte[]{'a','b','c'}; buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.flip(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } }
Output results
97
98
99
In the above case, a bytebuffer with a capacity of 10 is initialized
position=0, limit=capacity=10. In write mode, position is the write position, and limit is equal to capacity
After inserting a byte array
flip method
The default implementation of ByteBuffer is HeapByteBuffer
public final Buffer flip() { limit = position; position = 0; //Clear mark mark = -1; return this; }
After calling the flip method,
After switching to the read mode, the data will be read from position - > limit. After reading
Mark & & reset method
These two methods are mainly used to mark position and reset position to the marked position
public final Buffer mark() { mark = position; return this; } public final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; }
For example, if there is a need to re read the data from a position
public class ByteBufferDemo3 { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); byte[] bytes=new byte[]{'a','b','c'}; buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.flip(); System.out.println(buffer.get()); //sign int position = buffer.position(); System.out.println("stay position="+position+"Mark at"); buffer.mark(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } buffer.reset(); System.out.println("Again from position="+position+"Read data at"); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Output:
97
Mark position=1
98
99
Read the data from position=1 again
98
99
At first, after inserting the byte array, the buffer is as follows
After calling the flip and get() methods, the buffer is as follows
Buffer Mark() marks position=1
After the first traversal of the buffer from position=1
Call buffer Buffer after reset()
Therefore, you can read the data from position=1 again
clear method
public class ByteBufferDemo { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); byte[] bytes=new byte[]{'a','b','c'}; buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.clear(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Output result:
97
98
99
0
0
0
0
0
0
0
Through observation, it is found that the clear method can also flip the buffer. What is the difference between it and flip?
public final Buffer clear() { position = 0; limit = capacity; //Clear mark mark = -1; return this; }
It can be found that it sets the pointers in the buffer to the initial value.
At this time, if you read limit from position, you will read a lot of empty data. After reading, the buffer pointer is as follows
Therefore, if you want to use the clear method, try to ensure that the buffer data is full, otherwise useless data will be read out. Example
public class ByteBufferDemo2 { public static void main(String[] args) { byte[] bytes=new byte[]{'a','b','c'}; ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.clear(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Output result:
97
98
99
If you insert data again after the clear method, you need to pay attention, because the position position may change, resulting in incomplete read data.
public class ByteBufferDemo2 { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); byte[] bytes=new byte[]{'a','b','c'}; buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.clear(); buffer.put((byte) 100); //buffer.flip(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Output result:
98
99
0
0
0
0
0
0
0
The put method is called after the clear() method.
Because the put method moves position, the data just inserted cannot be read. If you don't want to move the position, you can try to specify the index when putting, so that the position won't be moved
Note: if the above buffer put((byte) 100); After calling the flip method, position=0 and limit=1 can only read characters inserted just now.
Therefore, when using the clear method, we should weigh how to get the data and how to get the data.
compact method
This method is different from the previous one. It compresses the unread part forward and then switches to write mode
public ByteBuffer compact() { //Copy data copy data from position, receive data from hbindex=0, copy length = limit position System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); //Reset buffer position position(remaining()); //Reset limit limit limit(capacity()); //Clear mark mark discardMark(); return this; }
Examples
public class ByteBufferDemo { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); byte[] bytes=new byte[]{'a','b','c'}; buffer.put(bytes); //Flip byteBuffer from write mode to read mode buffer.flip(); buffer.get(); buffer.compact(); buffer.put((byte) 'd'); buffer.put((byte) 'e'); buffer.flip(); while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Output result:
98
99
100
101
After calling the flip and get methods, the buffer is as follows
After the compact() method is called, the buffer is as follows
Because buffer was called earlier Get() so the original position=1 and the original limit=3
position=limit - original position=3-1=2, limit=capacity=10
After calling the put method twice again
The later read data will not be repeated.
summary
Don't forget to call the flip method when switching between read and write