In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the principle of Java NIO Buffer implementation". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1. The inheritance system of Buffer
As shown in the figure above, for all the basic types in Java, there will be a specific Buffer type corresponding to it, and generally we use ByteBuffer most frequently.
2. Use case of Buffer operation API
Give a use case of IntBuffer:
/ * @ author csp * @ date 2021-11-26 3:51 PM * / public class IntBufferDemo {public static void main (String [] args) {/ / allocate a new int buffer with the parameter of buffer capacity. / / the current position of the new buffer is 0, and its limit (limit position) is its capacity. It has an underlying implementation array with an array offset of 0. IntBuffer buffer = IntBuffer.allocate (8); for (int I = 0; I
< buffer.capacity(); i++) { int j = 2 * (i + 1); // 将给定整数写入此缓冲区的当前位置,当前位置递增。 buffer.put(j); } // 重设此缓冲区,将限制位置设置为当前位置,然后将当前位置设置为0。 buffer.flip(); // 查看在当前位置和限制位置之间是否有元素: while (buffer.hasRemaining()){ // 读取此缓冲区当前位置的整数,然后当前位置递增。 int j = buffer.get(); System.out.print(j + " "); } }} 运行结果: 2 4 6 8 10 12 14 16 从该案例中可以看出,其实本质上这里就是把IntBuffer看作成一个数组容器使用,可以通过get方法向容器中读取数据(put方法向容器中写入数据)。 3、Buffer的基本原理 Buffer缓冲区本质上就是一个特殊类型的数组对象,与普通数组不同的地方在于,其内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如果我们使用get()方法从缓冲区获取数据或者使用put()方法把数据写入缓冲区,都会引起缓冲区状态的变化。 Buffer内置数组实现状态变化与追踪的原理,本质上是通过三个字段变量实现的: position:指定下一个将要被写入或者读取的元素索引,它的值由get()/put()方法自动更新,在新创建一个Buffer对象时,position被初始化为0。 limit:指定还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。 capacity:指定了可以存储在缓冲区中的最大数据容量,实际上,它指定了底层数组的大小,或者至少是指定了准许我们 使用的底层数组的容量。 源码如下: public abstract class Buffer { // 三个字段属性之间的数值关系:0 = 0) { if (mark >Pos) throw new IllegalArgumentException ("mark > position: (" + mark + ">" + pos + ")"); this.mark = mark;}}
Is essentially equivalent to the following code:
/ / initialize a byte array byte [] bytes = new byte [10]; / / wrap the array to ByteBufferByteBuffer buffer = ByteBuffer.wrap (bytes); 5. Slice method buffer fragmentation
In Java NIO, you can create a subbuffer based on the first-used buffer Buffer object. That is, a piece is cut out of the existing buffer as a new buffer, but the existing buffer and the created sub-buffer are shared at the underlying array level.
The sample code is as follows:
/ * @ author csp * @ date 2021-11-28 6:20 p.m. * / public class BufferSlice {public static void main (String [] args) {ByteBuffer buffer = ByteBuffer.allocate (10); / / put data to the buffer: 0room9 for (int I = 0; I < buffer.capacity (); iSense +) {buffer.put ((byte) I) } / / create a subbuffer: that is, from the position 3 in the array to the position 7 in the array, buffer.position (3); buffer.limit (7); ByteBuffer slice = buffer.slice (); / / change the contents of the subbuffer for (int I = 0; I < slice.capacity (); ibuffer +) {byte b = slice.get (I) B * = 10; slice.put (I, b);} / / position and limit are restored to their original location: buffer.position (0); buffer.limit (buffer.capacity ()); / / output the contents of the buffer container: while (buffer.hasRemaining ()) {System.out.println (buffer.get ()) }}}
In this example, a buffer with a capacity of 10 is allocated and data 0room9 is placed in it, and a sub-buffer is created based on this buffer, and the contents of the sub-buffer are changed. from the final output, only the "visible" part of the data of the sub-buffer has changed, and indicates that the sub-buffer is shared with the original buffer, and the output result is as follows:
0
one
two
thirty
forty
fifty
sixty
seven
eight
nine
6. Read-only buffer
A read-only buffer, as its name implies, means that data can only be read from the buffer and cannot be written to it.
Let the existing buffer call the asReadOnlyBuffer () method to convert it to a read-only buffer. This method returns a buffer that is exactly the same as the original buffer and shares data with the original buffer, but it is read-only. If the content of the original buffer changes, so does the content of the read-only buffer.
The sample code is as follows:
/ * @ author csp * @ date 2021-11-28 6:33 p.m. * / public class ReadOnlyBuffer {public static void main (String [] args) {/ / initialize a buffer ByteBuffer buffer = ByteBuffer.allocate (10) with a capacity of 10; / / put data to the buffer: 0room9 for (int I = 0; I < buffer.capacity ()) ) {buffer.put ((byte) I);} / convert the buffer to a read-only buffer ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer (); / / because buffer and readOnlyBuffer essentially share a byte [] array object, / / changing the contents of the buffer buffer will cause the contents of the read-only buffer readOnlyBuffer to change as well. For (int I = 0; I < buffer.capacity (); iTunes +) {byte b = buffer.get (I); b * = 10; buffer.put (I, b);} / / position and limit restore to the original location: readOnlyBuffer.position (0); readOnlyBuffer.limit (buffer.capacity ()) / / output the contents of the readOnlyBuffer container: while (readOnlyBuffer.hasRemaining ()) {System.out.println (readOnlyBuffer.get ());}
The output is as follows:
0
ten
twenty
thirty
forty
fifty
sixty
seventy
eighty
ninety
If you try to modify the contents of a read-only buffer, a ReadOnlyBufferException exception is reported. You can only convert a regular buffer to a read-only buffer, not a read-only buffer to a writable buffer.
7. Direct buffer
Reference article: direct and indirect buffers of Java NIO learning articles
For the definition of direct buffers, the book "in depth understanding the Java Virtual Machine" is introduced as follows:
The Java NIO byte buffer (ByteBuffer) is either direct or indirect. If it is a direct byte buffer, the java virtual machine does its best to perform native IO operations directly on this buffer, that is, before and after each call to a native IO operation of the underlying operating system, the virtual machine tries to avoid copying the contents of the kernel buffer into the user process buffer or vice versa.
Direct buffers can be created by calling the allocateDirect (int capacity) method of the buffer class, which returns buffers that are more expensive to allocate and unallocate than indirect buffers. The contents of the direct buffers reside outside the garbage collection heap, so they require little application memory (JVM memory). Therefore, it is recommended that direct buffers be allocated to large, persistent buffers (that is, the buffer's data will be reused). In general, it is best to allocate direct buffers only if they bring obvious benefits to program performance.
A direct buffer can also be created by mapping the file area into memory through the map () method of FileCHannel, which returns MappedByteBuffer. The implementation of the Java platform facilitates the creation of direct byte buffers through JNI native code. If an instance of one of these buffers points to an inaccessible area of memory, an attempt to method that area does not change the contents of the buffer and causes an uncertain exception to be reported during access or at a later time.
Whether a byte buffer is a direct or indirect buffer can be determined by calling its isDIrect () method.
Case code:
/ * @ author csp * @ date 2021-11-28 7:07 afternoon * / public class DirectBuffer {public static void main (String [] args) throws IOException {/ / read the contents of the test.txt file from disk FileInputStream fileInputStream = new FileInputStream ("/ Users/csp/IdeaProjects/netty-study/test.txt"); / / the operation pipeline for creating the file FileChannel inputStreamChannel = fileInputStream.getChannel () / / write the read to the new file FileOutputStream fileOutputStream = new FileOutputStream ("/ Users/csp/IdeaProjects/netty-study/test2.txt"); FileChannel outputStreamChannel = fileOutputStream.getChannel (); / / create a direct buffer ByteBuffer byteBuffer = ByteBuffer.allocateDirect (1024); while (true) {byteBuffer.clear () Int read = inputStreamChannel.read (byteBuffer); if (read = =-1) {break;} byteBuffer.flip (); outputStreamChannel.write (byteBuffer);}
To allocate a direct buffer, you need to call the allocateDirect () method instead of the allocate () method, which is used in the same way as a normal buffer.
8. Memory mapping
Memory mapping is a way to read and write file data, which can be much faster than conventional stream-based or channel-based Imap O. The memory-mapped file Iwhite O is done by making the data in the file appear as the contents of a memory array, which at first sounds like reading the entire file into memory, but in fact this is not the case. In general, only the parts of the file that are actually read or written are mapped to memory. Take a look at the following sample code:
/ * @ author csp * @ date 2021-11-28 7:16 afternoon * / public class MapperBuffer {static private final int start = 0; static private final int size = 10; public static void main (String [] args) throws IOException {RandomAccessFile randomAccessFile = new RandomAccessFile ("/ Users/csp/IdeaProjects/netty-study/test.txt", "rw"); FileChannel channel = randomAccessFile.getChannel () / / make a mapping association between the buffer and the file system. As long as you manipulate the contents in the buffer, the file content will be changed accordingly MappedByteBuffer mappedByteBuffer = channel.map (FileChannel.MapMode.READ_WRITE, start, size); mappedByteBuffer.put (4, (byte) 97); / / a mappedByteBuffer.put (5, (byte) 122); / / z randomAccessFile.close ();}}
The original test.txt file is as follows:
Java
After executing the above code, the contents of the test.txt file are updated as follows:
Javaaz
This is the end of the content of "what is the principle of Java NIO Buffer implementation". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.