Original link Jakob Jenkov Translator:Airu proofreading: Ding
Buffer in Java NiO is used to interact with the NIO channel. As you know, the data is read from the channel into the buffer, written from the buffer to the channel.
A buffer is essentially a piece of memory in which data can be written and then read from it. This memory is packaged into a NiO buffer object and provides a set of methods for easy access to the block memory.
Below is a list of topics related to NIO buffer:
- Basic usage of buffer
- Capacity,position and limit for buffer
- Type of buffer
- Allocation of buffer
- Write data to Buffer
- Flip () method
- reading data from buffer
- Clear () and compact () methods
- Mark () and Reset () method
- Equals () and CompareTo () methods
Basic usage of buffer
Reading and writing data using buffer typically follows these four steps:
- Write data to Buffer
- Calling
flip()
methods
- reading data from buffer
- Calling a
clear()
method or compact()
method
When data is written to buffer, buffer records how much data is written. Once you are reading the data, you need to switch the buffer from write mode to read mode via the Flip () method. In read mode, all data written to 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 a buffer: Call the Clear () or compact () method. The clear () method empties the entire buffer. The compact () method clears only the data that has been read. Any unread data is moved to the beginning of the buffer, and the newly written data is placed behind the buffer's unread data.
Here is an example of using buffer:
01 |
RandomAccessFile aFile = new RandomAccessFile( "data/nio-data.txt" , "rw" ); |
02 |
FileChannel inChannel = aFile.getChannel(); |
04 |
//create buffer with capacity of 48 bytes |
05 |
ByteBuffer buf = ByteBuffer.allocate( 48 ); |
07 |
int bytesRead = inChannel.read(buf); //read into buffer. |
08 |
while (bytesRead != - 1 ) { |
10 |
buf.flip(); //make buffer ready for read |
12 |
while (buf.hasRemaining()){ |
13 |
System.out.print(( char ) buf.get()); // read 1 byte at a time |
16 |
buf.clear(); //make buffer ready for writing |
17 |
bytesRead = inChannel.read(buf); |
Capacity,position and limit for buffer
A buffer is essentially a piece of memory in which data can be written and then read from it. This memory is packaged into a NiO buffer object and provides a set of methods for easy access to the block memory.
To understand how the buffer works, you need to familiarize yourself with its three properties:
The meaning of position and limit depends on whether the buffer is in read or write mode. No matter what mode the buffer is in, the meaning of capacity is always the same.
Here is a description of the capacity,position and limit in the read-write mode, explained in detail behind the illustration.
Capacity
As a block of memory, buffer has a fixed size value, also known as "capacity". You can only write in capacity a byte, Long,char and other types. Once the buffer is full, it needs to be emptied (by reading the data or clearing the data) to continue writing the data.
Position
When you write data into buffer, position represents the current position. The initial position value is 0. When a byte, long, and other data is written to buffer, the position moves forward to the next buffer cell that can insert the data. The position can be capacity–1 maximum.
When reading data, it is also read from a specific location. When the buffer is switched from write mode to read mode, the position is reset to 0. When the data is read from the position in buffer, the position moves forward to the next readable position.
Limit
In write mode, the limit of buffer indicates how much data you can write to buffer. Write mode, limit equals buffer's capacity.
When you switch buffer to read mode, limit indicates how much data you can read. Therefore, when you toggle buffer to read mode, limit is set to the position value in write mode. In other words, you can read all the previously written data (limit is set to the number of written data, this value is position in write mode)
Type of buffer
Java NIO has the following buffer types
- Bytebuffer
- Mappedbytebuffer
- Charbuffer
- DoubleBuffer
- Floatbuffer
- Intbuffer
- Longbuffer
- Shortbuffer
P<>
As you can see, these buffer types represent different data types. In other words, the bytes in the buffer can be manipulated by a char,short,int,long,float or double type.
Mappedbytebuffer is a bit special, in the specialized chapters that cover it.
Allocation of buffer
To get a buffer object, you first need to allocate it. Each buffer class has a allocate method. The following is an example of a bytebuffer that allocates 48 bytes of capacity.
1 |
ByteBuffer buf = ByteBuffer.allocate( 48 ); |
This is the assignment of a charbuffer that can store 1024 characters:
1 |
CharBuffer buf = CharBuffer.allocate( 1024 ); |
Write data to Buffer
There are two ways of writing data to buffer:
- Write from channel to buffer.
- Write to buffer by using the put () method in buffer.
Example of writing from channel to buffer
1 |
int bytesRead = inChannel.read(buf); //read into buffer. |
Example of buffer written by the Put method:
There are many versions of the Put method that allow you to write data to buffer in different ways. For example, write to a specified location, or write a byte array to buffer. More details on buffer implementations refer to Javadoc.
Flip () method
The flip method switches buffer from write mode to read mode. Calling the flip () method resets position back to 0 and sets the limit to the value of the previous position.
In other words, position is now used to mark the read position, and limit indicates how many bytes, char, and so on have been written before--how many bytes, char, and so on can now be read.
reading data from buffer
There are two ways of reading data from buffer:
- Reads data from buffer to channel.
- Use the Get () method to read data from buffer.
Example of reading data from buffer to channel:
1 |
//read from buffer into channel. |
2 |
int bytesWritten = inChannel.write(buf); |
Example of using the Get () method to read data from buffer
The Get method has many versions that allow you to read data from buffer in different ways. For example, reading from a specified position, or reading data from buffer to a byte array. More details on buffer implementations refer to Javadoc.
Rewind () method
Buffer.rewind () sets the position back to 0, so you can reread all the data in the buffer. The limit remains unchanged and still indicates how many elements (Byte, char, and so on) can be read from the buffer.
Clear () and compact () methods
Once you have finished reading the data in buffer, you need to make buffer ready to be written again. Can be done through the clear () or compact () method.
If the call is the clear () method, position will be set back to the value 0,limit to capacity. In other words, Buffer is emptied. The data in buffer is not cleared, but these tags tell us where we can start writing data to buffer.
If there are some unread data in buffer and the clear () method is called, the data will be "forgotten", meaning no more tags will tell you what data has been read or not.
If you still have unread data in buffer and you need that data 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. The position is then set to the last unread element just behind it. The Limit property is still set to capacity, just like the clear () method. Now buffer is ready to write the data, but it will not overwrite the unread data.
Mark () and Reset () method
By calling the Buffer.mark () method, you can mark a specific position in buffer. You can then revert to this position by calling the Buffer.reset () method. For example:
3 |
//call buffer.get() a couple of times, e.g. during parsing. |
5 |
buffer.reset(); //set position back to mark. |
Equals () and CompareTo () methods
You can use the Equals () and CompareTo () methods two buffer.
Equals ()
Two buffer equals when the following conditions are met:
- Have the same type (byte, char, int, and so on).
- The remaining number of Byte, char, and so on in buffer is equal.
- All remaining byte, char, and so on in buffer are the same.
As you can see, equals is just a part of the comparison buffer, not every element in it is compared. In fact, it compares only the remaining elements in buffer.
CompareTo () method
The CompareTo () method compares the remaining elements of two buffer (byte, char, and so on) and considers a buffer "less than" another buffer if the following conditions are true:
- 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 number of elements in the first buffer is less than the other one).
(Note: The remaining elements are elements from position to limit)
original articles, reproduced please specify: reproduced from the Concurrent programming network –ifeve.com This article link address: Java NiO Series Tutorial (iii) Buffer
Java NiO Series Tutorial (iii) Buffer