Explanation of common ByteBuffer methods and bytebuffer
Buffer)
A Buffer is a storage space with a specified size reserved in the memory for temporary storage of input/output (I/O) data. This reserved memory space is called a Buffer zone:
There are two advantages to using a buffer:
1. Reduce the actual number of physical reads and writes
2. the buffer zone is allocated with memory when it is created. This memory area is reused all the time and can reduce the number of times of dynamic memory allocation and recovery.
A simple example is as follows: for example, there are 1 W bricks to be moved to B.
Since there is no tool (buffer zone), we can only move one copy at a time, so we need to move one million (actual read/write times)
If A and B are far away (IO performance consumption), the performance consumption will be very high.
But if we have a large truck (buffer zone) that can run 5000 at a time, it would be enough for two times.
Compared with the previous one, the performance must be greatly improved.
Therefore, buffer is very important in IO. Buffer is used in the implementation of BufferedInputStream, BufferedOutputStream, BufferedReader, and BufferedWriter in the old I/O class library (compared to the java. nio package. The java. nio package exposes the Buffer API so that Java programs can directly control and use the Buffer.
In Java NIO, the buffer is used to temporarily store data. It can be understood as a transfer station for data in I/O operations. The buffer zone is a Channel service that writes data to or reads data from the Channel. This operation uses the buffer zone data for transmission to achieve efficient data processing. There are mainly eight buffer classes in NIO (MappedByteBuffer is a kind of ByteBuffer dedicated for memory ing ):
Fields
Each buffer has four attributes: capacity, limit, position, and mark, and follows: mark <= position <= limit <= capacity. The following table describes the four attributes:
Attribute |
Description |
Capacity |
Capacity, that is, the maximum amount of data that can be accommodated. It is set when the buffer is created and cannot be changed. |
Limit |
Indicates the current endpoint of the buffer. You cannot perform read/write operations on the locations where the buffer exceeds the limit. And the limit can be modified. |
Position |
Location, the next index of the element to be read or written, changes the value every time the buffer data is read and written, to prepare for the next read/write |
Mark |
Mark, call mark () to set mark = position, and then call reset () to restore position to the marked position. |
Methods
1. instantiation
The java. nio. Buffer class is an abstract class and cannot be instantiated. The direct subclass of the Buffer class, such as ByteBuffer, is also an abstract class, so it cannot be instantiated.
However, the ByteBuffer class provides four static factory methods to obtain ByteBuffer instances:
Method |
Description |
Allocate (int capacity) |
Allocate a buffer size byte array from the heap space as the byte data storage of the buffer. |
AllocateDirect (int capacity) |
Instead of using the JVM stack, the memory block is created through the operating system and used as a buffer. It can be better coupled with the current operating system, thus further improving the I/O operation speed. However, the system overhead of allocating a direct buffer is very large. Therefore, this buffer is used only when the buffer is large and long-lived, or often needs to be reused. |
Wrap (byte [] array) |
The data in this buffer zone will be stored in the byte array. Changes to the data in the bytes array or the buff buffer will affect the other side. In fact, there is a bytes array at the bottom layer of ByteBuffer to store the data in the buffer. The allocate method will help you construct a byte array. |
Wrap (byte [] array, Int offset, int length) |
You can specify the offset and length based on the previous method. This offset is the position of byteBuffer After packaging, and the length is the size of limit-position, in this way, we can see that the limit position is length + position (offset) |
I have written the test methods for these methods, so it is easier to understand.
Public static void main (String args []) throws FileNotFoundException {System. out. println ("---------- Test allocate --------"); System. out. println ("before alocate:" + Runtime. getRuntime (). freeMemory (); // If the allocated memory is too small, call Runtime. getRuntime (). does freeMemory () size change? // How much memory does the JVM feel when it exceeds? ByteBuffer buffer = ByteBuffer. allocate (1, 102400); System. out. println ("buffer =" + buffer); System. out. println ("after alocate:" + Runtime. getRuntime (). freeMemory (); // This part is directly used in the system memory, so it does not affect the JVM memory ByteBuffer directBuffer = ByteBuffer. allocateDirect (102400); System. out. println ("directBuffer =" + directBuffer); System. out. println ("after direct alocate:" + Runtime. getRuntime (). freeMemory (); System. out. println ("---------- Test wrap --------"); byte [] bytes = new byte [32]; buffer = ByteBuffer. wrap (bytes); System. out. println (buffer); buffer = ByteBuffer. wrap (bytes, 10, 10); System. out. println (buffer );}
2. Other common methods
Method |
Description |
Limit (), limit (10), etc. |
The names of the methods for reading and setting these four attributes are similar to val () and val (10) In jQuery. One is responsible for get and the other is responsible for set |
Reset () |
Set position to the mark value, which is equivalent to a mark previously made. Now, you need to return it to the previously marked place. |
Clear () |
Position = 0; limit = capacity; mark =-1; a bit of initialization taste, but does not affect the content of the underlying byte array |
Flip () |
Limit = position; position = 0; mark =-1; flip, that is, to change the position to limit after flip to the previous 0 to position, turning is to change a buffer in the state of data storage to a state in which data is prepared. |
Rewind () |
Set position to 0 and mark to-1 without changing the limit value. |
Remaining () |
Return limit-position; return the relative position difference between limit and position. |
HasRemaining () |
Return position <limit: whether there is any unread content returned |
Compact () |
Move the content from position to limit to the range from 0 to limit-position. The values of position and limit are also changed to limit-position and capacity. If you set positon to limit and then compact, it is equivalent to clear () |
Get () |
Read a byte from the position and add position + 1 to prepare for the next read/write operation. |
Get (int index) |
Absolute read: reads byte marked as index in byteBuffer's underlying bytes, without changing the position |
Get (byte [] dst, int offset, int length) |
Start relative read from position, read length byte, and write the dst subscript from offset to offset + length. |
Put (byte B) |
Write a byte to the position, and write the postion + 1 to prepare for the next read/write. |
Put (int index, byte B) |
Absolute write: insert byte B to the position marked as index in byteBuffer's underlying bytes without changing the position |
Put (ByteBuffer src) |
Write the readable part (that is, position to limit) in src to this byteBuffer |
Put (byte [] src, int offset, int length) |
Read data from offset to offset + length in the src array and write data to this byteBuffer using relative write. |
The following are some test methods:
Public static void main (String args []) {System. out. println ("-------- Test reset ----------"); buffer. clear (); buffer. position (5); buffer. mark (); buffer. position (10); System. out. println ("before reset:" + buffer); buffer. reset (); System. out. println ("after reset:" + buffer); System. out. println ("-------- Test rewind --------"); buffer. clear (); buffer. position (10); buffer. limit (15); System. out. println ("before rewind:" + buffer); buffer. rewind (); System. out. println ("before rewind:" + buffer); System. out. println ("-------- Test compact --------"); buffer. clear (); buffer. put ("abcd ". getBytes (); System. out. println ("before compact:" + buffer); System. out. println (new String (buffer. array (); buffer. flip (); System. out. println ("after flip:" + buffer); System. out. println (char) buffer. get (); System. out. println (char) buffer. get (); System. out. println (char) buffer. get (); System. out. println ("after three gets:" + buffer); System. out. println ("\ t" + new String (buffer. array (); buffer. compact (); System. out. println ("after compact:" + buffer); System. out. println ("\ t" + new String (buffer. array (); System. out. println ("------ Test get -------------"); buffer = ByteBuffer. allocate (32); buffer. put (byte) 'A '). put (byte) 'B '). put (byte) 'C '). put (byte) 'd '). put (byte) 'E '). put (byte) 'F'); System. out. println ("before flip ()" + buffer); // convert to read mode buffer. flip (); System. out. println ("before get ():" + buffer); System. out. println (char) buffer. get (); System. out. println ("after get ():" + buffer); // get (index) does not affect the position value System. out. println (char) buffer. get (2); System. out. println ("after get (index):" + buffer); byte [] dst = new byte [10]; buffer. get (dst, 0, 2); System. out. println ("after get (dst, 0, 2):" + buffer); System. out. println ("\ t dst:" + new String (dst); System. out. println ("buffer now is:" + buffer); System. out. println ("\ t" + new String (buffer. array (); System. out. println ("-------- Test put -------"); ByteBuffer bb = ByteBuffer. allocate (32); System. out. println ("before put (byte):" + bb); System. out. println ("after put (byte):" + bb. put (byte) 'Z'); System. out. println ("\ t" + bb. put (2, (byte) 'C'); // put (2, (byte) 'C') does not change the position of the System. out. println ("after put (2, (byte) 'C'):" + bb); System. out. println ("\ t" + new String (bb. array (); // The buffer here is abcdef [pos = 3 lim = 6 cap = 32] bb. put (buffer); System. out. println ("after put (buffer):" + bb); System. out. println ("\ t" + new String (bb. array ()));}
I have summarized ByteBuffer myself. I hope you can advise on any shortcomings!
Contains the help document of apache mina commonbyteBuffer. This class is not found in several examples.
The new version of Mina has no ByteBuffer and is replaced by IoBuffer. This class is for java. nio. an alternative to ByteBuffer (as to why it should be replaced, because people think that java. nio. byteBuffer is not powerful ). The Mina API documentation is too simple. You can only read the code and comments in the source code to learn more.
If you want to know about the IoBuffer of Mina (not called ByteBuffer now), just read java. nio. ByteBuffer.
Common methods include:
Allocate, put, get, clear, flip, limit, position, mark, reset...
After reading java. nio. ByteBuffer, you can understand IoBuffer (that is, the ByteBuffer of Mina.
What are the characteristics of java byte [] and ByteBuffer as intermediate caches?
Direct vs. non-direct buffers
A byte buffer is either direct or non-direct. given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. that is, it will attempt to avoid copying the buffer's content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system's native I/O operations.
A direct byte buffer may be created by invoking the allocateDirect factory method of this class. the buffers returned by this method typically have somewhat higher allocation and deallocation costs than non-direct buffers. the contents of direct buffers may reside outside of the normal garbage-collected heap, and so their impact upon the memory footprint of an application might not be obvious. it is therefore recommended that direct buffers be allocated primarily for large, long-lived buffers that are subject to the underlying system's native I/O operations. in general it is best to allocate direct buffers only when they yield a measureable gain program performance.
A direct byte buffer may also be created by mapping a region of a file directly into memory. an implementation of the Java platform may optionally support the creation of direct byte buffers from native code via JNI. if an instance of one of these kinds of buffers refers to an inaccessible region of memory then an attempt to access that region will not change the buffer's content and ...... remaining full text>