JAVA NIO Buffer Buffer

Buffer

Buffers in Java NIO are used to interact with NIO channels. As you know, data is read from the channel into the buffer, and written from the buffer to the channel. 
A buffer is essentially a block of memory to which data can be written and then read from it. This piece of memory is wrapped as a NIO Buffer object and provides a set of methods for easy access to this piece of memory. 

Basic usage of Buffer The 
use of Buffer to read and write data generally follows the following four steps: 

  • Write data to Buffer
  • call flip() method
  • read data from buffer
  • Call the clear() method or the compact() method
When writing data to the buffer, the buffer records how much data was written. Once the data is to be read, the Buffer needs to be switched from the write mode to the read mode by the flip() method. In read mode, all data previously written to the buffer can be read. 

Once all the data has been read, the buffer needs to be emptied so that it can be written again. There are two ways to clear the buffer: call the clear() or compact() method. The clear() method will clear the entire buffer. The compact() method will only clear data that has already been read. Any unread data is moved to the beginning of the buffer, and newly written data is placed after the unread data in the buffer. 

Here is an example using Buffer: 
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");  
FileChannel inChannel = aFile.getChannel();  
  
//create buffer with capacity of 48 bytes  
ByteBuffer buf = ByteBuffer.allocate(48);  
  
int bytesRead = inChannel.read(buf); //read into buffer.  
while (bytesRead! = -1) {  
  
  buf.flip();  //make buffer ready for read  
  
  while(buf.hasRemaining()){  
      System.out.print((char) buf.get()); // read 1 byte at a time  
  }  
  
  buf.clear(); //make buffer ready for writing  
  bytesRead = inChannel.read(buf);  
}  
aFile.close();  
Buffer's capacity, position and limit 

A buffer is essentially a block of memory to which data can be written and then read from it. This piece of memory is wrapped as a NIO Buffer object and provides a set of methods for easy access to this piece of memory. 

In order to understand how Buffer works, you need to be familiar with its three properties: 

  • capacity
  • position
  • limit
The meaning of position and limit depends on whether the Buffer is in read mode or write mode. No matter what mode the Buffer is in, the meaning of capacity is always the same. 

Here is a description of capacity, position and limit in read and write mode, the detailed explanation is after the illustration. 


capacity 
As a memory block, Buffer has a fixed size value, also called "capacity". You can only write capacity bytes, long, char and other types into it. Once the Buffer is full, it needs to be emptied (by reading data or clearing data) to continue writing data to it. 

position 
When you write data to the Buffer, position represents the current position. The initial position value is 0. When a byte, long and other data are written to the Buffer, the position will move forward to the next Buffer unit where data can be inserted. position can be up to capacity – 1. 
When reading data, it is also reading from a specific location. When switching the Buffer from write mode to read mode, position will be reset to 0. When reading data from the Buffer's position, the position is moved forward to the next readable position. 

limit 
In write mode, the limit of the Buffer indicates how much data you can write to the Buffer at most. In write mode, limit is equal to the capacity of Buffer. 

When switching Buffer to read mode, limit indicates how much data you can read at most. Therefore, when switching the buffer to read mode, limit will be set to the position value in write mode. In other words, you can read all the previously written data (the limit is set to the number of written data, which is the position in write mode) 

Types of Buffer 

Java NIO has the following Buffer types: 

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer
As you can see, these Buffer types represent different data types. In other words, the bytes in the buffer can be manipulated through the char, short, int, long, float or double type. 
MappedByteBuffer is a bit special and will be covered in a dedicated chapter on it. 

Buffer allocation 
To obtain a Buffer object, you must first allocate it. Every Buffer class has an allocate method.

ByteBuffer buf = ByteBuffer.allocate(48);
CharBuffer buf = CharBuffer.allocate(1024); 

Write 
data to Buffer There are two ways to write data to Buffer: 

  • Write from Channel to Buffer.
  • Write to Buffer through Buffer's put() method.
int bytesRead = inChannel.read(buf); //从channel写
buf.put(127); //Write by put method

There are many versions of the put method, allowing you to write data to the Buffer in different ways. For example, writing to a specified location, or writing an array of bytes to Buffer. Refer to the JavaDoc for more details on the Buffer implementation.

flip() method 
The flip method switches the Buffer from write mode to read mode. Calling the flip() method will set the position back to 0 and set the limit to the previous position value. 
In other words, position is now used to mark the read position, and limit indicates how many bytes, chars, etc. were written before - how many bytes, chars, etc. can be read now. 
Reading data 
from Buffer There are two ways to read data from Buffer: 

  • Read data from Buffer to Channel.
  • Use the get() method to read data from the Buffer.
//read from buffer into channel.  
int bytesWritten = inChannel.write(buf);  
byte aByte = buf.get();
There are many versions of the get method, allowing you to read data from the Buffer in different ways. For example, read from the specified position, or read data from the Buffer to a byte array. Refer to the JavaDoc for more details on the Buffer implementation. 

The rewind() method 
Buffer.rewind() sets the position back to 0, so you can reread all the data in the Buffer. The limit remains the same, still indicating how many elements (byte, char, etc.) can be read from the Buffer. 

Once the clear() and compact() methods have 
read the data in the Buffer, the Buffer needs to be ready to be written again. This can be done with the clear() or compact() methods. 
If the clear() method is called, position will be set back to 0 and limit will be set to the value of capacity. In other words, the Buffer is emptied. The data in the buffer is not cleared, but these flags tell us where to start writing data to the buffer. 
If there is some unread data in the Buffer, call the clear() method and the data will be "forgotten", meaning there will no longer be any markers that will tell you which data has been read and which has not. 
If there is still unread data in the Buffer, and the data is needed later, but you want to write some data first, use the compact() method.
The compact() method copies all unread data to the beginning of the Buffer. Then set the position to just after the last unread element. The limit property is still set to capacity like the clear() method. The buffer is now ready to write data, but will not overwrite unread data. 

mark() and reset() methods 
A specific position in the Buffer can be marked by calling the Buffer.mark() method. This position can then be restored by calling the Buffer.reset() method. E.g: 
buffer.mark();  //call buffer.get() a couple of times, e.g. during parsing.  
buffer.reset();  //set position back to mark.
equals() and compareTo() methods 

Two Buffers can be compared using the equals() and compareTo() methods. 

equals() 
means that two Buffers are equal when the following conditions are met: 
  • have the same type (byte, char, int, etc.).
  • The number of bytes, chars, etc. remaining in the Buffer is equal.
  • All remaining bytes, chars, etc. in the Buffer are the same.
As you can see, equals only compares part of the Buffer, not every element in it is compared. Actually, it only compares the remaining elements in the Buffer. 

compareTo() method 
compareTo() method compares the remaining elements (byte, char, etc.) of two Buffers. One Buffer is considered to be "less than" the other Buffer if the following conditions are met: 
  • The first unequal element is smaller than the corresponding element in the other Buffer.
  • All elements are equal, but the first buffer is exhausted before the other (the first buffer has fewer elements than the other).


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325947784&siteId=291194637