Directory[?]
- Member of the Buffer abstract class
- Property Properties
- Operation method
- Sub-class of buffer
- Bytebuffer: The most generic subclass that handles byte data types.
- Charbuffer
- DoubleBuffer
- Floatbuffer
- Intbuffer
- Longbuffer
- Shortbuffer
- Mappedbytebuffer
- Creation of buffer
- Direct buffers and indirect buffers
- Reference
In Java 1.4, the buffer class is added to the Java.nio package and some subclasses of the basic data type (except the Boolean) are provided to provide a container for data of the base data type (primitive).
What is buffer? Buffer is a linear finite-length sequence of specific basic data. In addition to the underlying data, it includes some basic operations and properties, such as capacity, limit, and position.
Use specific subclasses to process the data in practice. Each subclass defines two sets of get/put operations.
- relative position operation (Relative). Reads and writes one or more elements from the current position position, and position increases the corresponding values. If the data for a GET request exceeds the limit position, a Bufferunderflowexception exception is thrown. If a put operation exceeds limit limits, a Bufferoverflowexception exception is thrown. Regardless of the above, no data is transmitted.
- Absolute Position operation (Absolute). Providing index explicitly does not affect the value of position. An Indexoutofboundsexception exception is thrown if the index exceeds limit.
Data can also be written to or read through the channel's I/O operations such as Write,read.
It is clear that buffer can read data only if it is written to data.
The buffer class is not thread-safe and should be used with special care to avoid having to read and write the same buffer at the same time. As a last resort, you need to lock the read and write operations.
the difference between cache and buffer
From the application scenario: Buffer More (scene) is to reduce the impact of write operations, and the Cache is mainly used to reduce the duplication of read I/O costs.
Member of the Buffer abstract class
Buffer provides a series of methods and properties for manipulating buffers. However, properties are not provided as field fields, but are provided in method mode.
Property Properties
- Capacity (): As mentioned above, the elements in buffer are finite. This value represents the maximum number of elements in buffer. This value will not be negative and will not be changed.
- Limit (): In many cases, the buffer is not filled. Limit is the index position of the first data that should not be read/written. Obviously this value cannot be a negative number, nor will it exceed the value of capacity.
- Position (): The next index of data to be read/written. cannot be negative or exceed the value of limit.
- Mark: The index being tagged. Calling the Reset method sets the value of position to the value of Mark. This allows you to re-read/write buffer data. When the value of position or limit is less than its value, its value is discarded. Its value cannot be negative, it will not exceed the value of position, it may not be set, and calling the Reset method throws a Invalidmarkexception exception if it is not set. There is no direct read method.
- Remaining (): Returns the difference between position and limit, which is the number of unread/written data.
Operation method
- reset Reset. Resets the value of position to the value of Mark. This method does not change Mark's value, nor does it discard the mark's value.
- clear empty. Clears the buffer. The value of position set to 0, limit value of Capacity,mark is discarded. This method is typically called before the buffer is populated: buf.clear (); In.read (BUF);. This method does not erase previously populated data, but is functionally the same in the case of actual use. The
- flip is reversed. Reversing the buffer sets the value of limit to the value of position, and then the value of position is set to 0. If Mark is set, it will be discarded. This method is generally called when reading and writing data after populating the buffer: Buf.put (Magic); In.read (BUF); Buf.flip (); Out.write (BUF);
- rewind fallback. position set to 0, mark value is discarded and the value of limit is not changed. Similar to the flip above, but flip will change the value of limit, but remind will not. Application scenario: out.write (BUF); Buf.rewind (); Buf.get (array);
- mark () mark the current position. Set mark with the value of position.
Clear,flip,limit (Newlimit), Mark,position (newposition), reset () and rewind return their own buffer, which means you can use streaming style, such as
Buffer.flip (). Position (at). Limit (42);
Keep in mind the following formula, where the following inequalities are established at all times:
0 <= Mark <= position <= limit <= capacity
The position of a newly created buffer is always 0, and mark is undefined. The initial limit might be 0, or another positive value, depending on the type of buffer and how it was created. The initialized buffer contains 0 elements.
In addition, buffer provides a number of other Members:
- Array: Returns the underlying array implementation. If the underlying is not using an array implementation, or is read-only, the exception may be thrown readonlybufferexception, unsupportedoperationexception. HasArray is called to determine whether an array is supported before it is used normally. Changes to the contents of the buffer affect the value of the array and vice versa.
- The value p of the Arrayoffset:buffer position corresponds to the P + arrayoffset () of the array, which is the offset value of the first element of buffer in the array.
- HasArray: Determine if buffer has a bottom-level array implementation.
- Whether there are elements before hasremaining:position and limit.
- IsReadOnly: Whether it is read-only.
- Whether the Isdirect:buffer is a direct 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.
Note that it only compares the remaining parts.
CompareTo ()
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.
- The preceding elements are equal, but the remaining elements in the first buffer are less than the other one.
Sub-class of buffer
Buffer is an abstract class. What we actually use is its subclass, which is primarily optimized for basic data types.
Bytebuffer: The most generic subclass that handles byte data types.
Provides a way to get/put a single byte or byte array, or a relative and absolute operation.
Bytes are the basis for other basic data types. For example, the int type is 32 bits or 4 bytes.
Data Type |
size (byte) |
Byte |
1 |
Short |
2 |
Int |
4 |
Long |
8 |
Float |
4 |
Double |
8 |
Char |
2 |
Therefore, you can write data from these basic data types into a byte buffer or read from it.
Bytebuffer defines a convenient method for basic data types, such as GetChar (), GetInt (), Putfloat,putshort ... and other methods.
Note Putxxx may throw bufferoverflowexception and readonlybufferexception exceptions, getxxx may throw bufferunderflowexception exceptions.
Bytebuffer also provides a way to create view views. Other basic types of buffer can be created based on Bytebuffer, and their underlying data points to an object, but the corresponding position, limit, and Mark are independent. For example, Asintbuffer () returns an Intbuffer object that returns an element of the Intbuffer object that corresponds to the location of the position of this bytebuffer. The value of Intbuffer position is 0,capacity and limit is the number of bytes remaining for this Bytebuffer/4 (int is four bytes), Mark is undefined. This intbuffer is a direct buffer when and only if Bytebuffer is a direct buffer, and only if Bytebuffer is read-only Intbuffer is read-only.
Note that Bytebuffer is still an abstract class, and the allocate method and the Allocatedirect method create the buffer when the Heapbytebuffer or Directbytebuffer class is actually created.
Streaming style is still supported. Bb.putint (0xCAFEBABE). Putshort (3). Putshort (45);
Asreadonlybuffer () is converted to a read-only buffer. New buffers of position, limit, and Mark are independent. The initial value is the same as the original buffer.
Duplicate copy the current bytebuffer, the underlying data is common, but Position,capacity,limit, Mark is independent, The Bytebuffer method returns the initial ownership of the same position,capacity,limit as the original Bytebuffer, Mark.
Slice () is also a new byte buffer, and the data is shared with the original bye buffer. However, the new byte buffer will start at the location of the position in the original byte buffer. This is what slice means.
There are two methods of allocate (int capacity) and allocatedirect (int capacity).
Wrap (byte[] array), wrap (byte[] array, int offset, int length) wraps the byte array into Bytebuffer.
Order () and order (Byteorder Bo) are used to return and set the byte order: big-endian mode (Big_endian) and small-end mode (Little_endian). The default is always the big-endian mode (Big_endian).
Compact: Compression Bytebuffer. Copies the data between position and limit to the beginning of the buffer. For example, p = position, the data at p + 1 is copied to index 1 ... the data at Limit-1 is copied to n = limit-1-P. The position of the buffer is set to n+1, and the limit is set to capacity, and Mark discards.
The following subclasses are similar to Bytebuffer, but do not convert to other buffer methods and views. This is easy to understand because byte is the base unit for other basic data types.
Wrap wraps an array of the corresponding base data types. There are still compact, duplicate, slice methods. Streaming style, get/put single data operation and batch operation, relative position operation and absolute position operation.
Charbuffer
Provides the Append method, which is equivalent to the Put method.
charAt (int index) returns the character at the specified position.
subsequence (int start, int end) returns the buffer at the specified position. Share data with the original buffer. Capacity the same. The position of the new buffer is the original buffer position + start, and the limit is the position + end of the original buffer. Direct, ReadOnly is the same as the original buffer.
DoubleBuffer
Processes double type data.
Floatbuffer
Handles float type data.
Intbuffer
processes int type data.
Longbuffer
Handles long type data.
Shortbuffer
Process short type data.
Mappedbytebuffer
Inherit from Bytebuffer. It is a direct byte buffer based on a memory-mirrored file. Can be created through Filechannel.map.
Force () forces a change to the data to be written to the storage device.
IsLoaded (): Whether the data in the buffer is all loaded into physical memory.
Load (): Loads the buffer's data into physical memory.
A memory-mapped file is a special file that allows Java programs to access directly from memory. By mapping an entire file or part of a file into memory, the operating system is responsible for fetching page requests and writing files, the application only needs to process the memory data, which allows for very fast IO operations. The memory used for the memory-mapped file is outside the heap space of Java.
Creation of buffer
- Wrapping an array
Charbuffer cb = charbuffer.allocate (1024); Bytebuffer BB = bytebuffer.allocatedirect (1024*1024);
- memory mapping, which is called the map () method of FileChannel
FileChannel fc = new Randomaccessfile ("Test.data", "RW"). Getchannel (); Mappedbytebuffer out = Fc.map (FileChannel.MapMode.READ_WRITE, 0, length);
Direct buffers and indirect buffers
Byte buffer can be a direct buffer that may be a non-direct buffer. For direct buffers, Java virtual machines are most likely to perform native I/O operations directly, avoiding the need to replicate content to an intermediate buffer when operating system native I/O operations.
It allocates out-of-heap memory directly using the native library, and then operates through a Directbytebuffer object stored in the Java heap as a reference to this memory.
Direct buffers can be created directly through the Allocatedirect factory method, which internally creates Directbytebuffer objects and allocates memory through Unsafe.allocatememory. In contrast, this method returns a buffer that is a bit more expensive to allocate/destroy than the non-direct buffer (time and space). The direct buffer is outside the garbage collection heap, so it is recommended to use it primarily for large long-time active buffers, which can indeed be used to raise high performance environments.
You can also use the direct buffer Filechannel.map in the way that the memory mirrors the file. The Java platform can optionally use JNI to create a direct buffer. If buffer points to an inaccessible area of memory, the contents of the buffers are not changed, and access operations can result in an indeterminate exception.
You can determine whether a buffer is a direct buffer by the Isdirect method.
Although the direct buffer is out-of-heap memory, because directbytebuffer references it, when Directbytebuffer is garbage collected, this out-of-heap memory is freed and there is no memory leak issue.
Java Buffer Programming Basics