Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the use of Buffer buffer in Java NIO

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the use of Buffer buffer in Java NIO. It is very detailed and has certain reference value. Friends who are interested must finish reading it.

A brief introduction to Buffer

The Buffer in Java NIO is used to interact with the NIO channel. The data is read into the buffer by the channel

A buffer is essentially a piece of memory from which data can be written and then read. This piece of memory is wrapped in NIO Buffer objects and provides a set of methods to easily access the block of memory. In the last century, a buffer container object is, more directly, an array. In the NIO library, all data is processed with a buffer. When reading data, it reads directly into the buffer; when writing data, it is also written to the buffer; whenever the data in NIO is accessed, it is put into the buffer. In the stream-oriented Iramp O system, all data is written directly or read directly into the Stream object.

In NIO, all buffer types inherit from the abstract class Buffer, and the most commonly used one is ByteBuffer. For the basic types of Java China, the amount has a specific Buffer type corresponding to it, and the inheritance relationship between them is shown in the following figure:

2. The basic method of Buffer 1. Use Buffer to read and write data

To read and write data using Buffer, you generally follow the following four steps:

(1) write data to Buffer

(2) call the flip () method

(3) read data from Buffer

(4) call clear () method or compact () method

When writing data to buffer, buffer records how much data has been written. Once you want to read the data, you need to switch the buffer from write mode to read mode through the flip () method. In read mode, all data previously written to buffer can be read. Once you have read all the data, you need to clear the buffer so that it can be written again. There are two ways to empty the buffer: call the clear () or compact () method. The clear () method clears the entire buffer. The compact () method clears only the data that has passed. Any unread data is moved to the beginning of the buffer, and the newly written data is placed after the buffer unread data.

2. Example of using Buffer @ Testpublic void buffer01 () throws IOException {/ / FileChannel String pathName = "/ Users/zhengsh/sourcecode.io/zhengsh-vvip/nio/src/main/resources/01.txt"; RandomAccessFile accessFile = new RandomAccessFile (pathName, "rw"); FileChannel channel = accessFile.getChannel (); / / create buffer, size ByteBuffer buffer = ByteBuffer.allocate (1024); / / read int bytesRead = channel.read (buffer) While (bytesRead! =-1) {/ / read mode buffer.flip (); while (buffer.hasRemaining ()) {System.out.println (char) buffer.get ());} buffer.clear (); channel.read (buffer);} accessFile.close ();} @ Testpublic void buffer02 () {/ / create buffer IntBuffer buffer = IntBuffer.allocate (8) For (int I = 0; I

< buffer.capacity(); i++) { int j = 2 * (i + 1); buffer.put(j); } // 重置缓冲区 buffer.flip(); while (buffer.hasRemaining()) { int value = buffer.get(); System.out.println(value + " "); }}三、Buffer 的 capactity、posittion 和limit 为了理解 Buffer 的工作原理,需要熟悉它的三个属性: capacity ponstition limit position 和 limit 的含义取决于 Buffer 处在读模式还是写模式。不管 buffer 处于什么模式,capactity 的含义总是一样的。 这里有一个关于 capacity, postition 和 limit 在读模式中的说明: (1) capactiy 作为一个内存块,Buffer 有一个固定的大小值,也叫做 "capactiy" . 你只能往里面写 capacity 个 byte long、 char等类型。一旦 buffer 满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。 (2) postition 1)写数据到 Bufer 中时,position 表示写入数据的当前位置,position 的初始值为 0 。当一个 byte,long,等数据写入到 buffer 后,position 会向下移动到下一个可插入的元素的 buffer 但愿。position 最大可为 capacity -1 (因为 position 的初始值为 0) 2)读数据到 Buffer 中时,position 表示读数据的当前位置,如 position = 2 时表示已经开始读了 3 个 byte, 或者从第三个 byte 开始读取,通过 ByteBuffer.flip() 切换到读模式 position 会被重置为 0, 当 Buffer 从 position 读入数据后,position 会下移到下一个可读入的数据 Buffer 单元。 (3) limit 1)写数据时, limit 表示可以对 Buffer 最多写入多少个数据。写模式下,limit 等于 Buffer 的 capactiy 2)读数据时, limit 表示 Buffer 里有多少可读数据(not null 的数据),因此能读取到之前写入的所有数据(limit 被设置为已写数据的数量,这个值在写模式下就是 position) 四、Buffer 的类型 Java NIO 有一下 Buffer 的类型 ByteBuffer MappedByteBuffer CharBuffer DoubleBuffer FloatBuffer LongBuffer ShortBuffer 这些 buffer 类型都代表了不同的数据类型。换句话说,就是可以通过 char ,short, int, long , float 或者 double 类型来操作缓冲区的字节。 五、Buffer 分配和写数据1、 Buffer 分配 想要获取一个 Buffer 对象首先要进行分配。每一个 Buffer 类都有一个 allocate 方法。 下面是一个分配 48 字节 capactiy 的 ByteBuffer 的例子。 ByteBuffer buf = ByteBuffer.alloacte(48); 这是分配一个可存储 1024 个字符的 CharBuffer: ByteBuffer buf = ByteBuffer.alloacte(1024);2、向 buffer 中写数据 写数据到 Buffer 有两种方式: (1)从 channel 写到 Buffer (2)通过 Buffer 的 put 方法写到 Buffer 里。 从 Channel 写到 Buffer 的例子 int byteRead = channel.read(buf); // read into buffer 通过 put 方法写入 buffer 的例子: buf.put(100); put 的方法有很多版本,允许你不同的方式把数据写入到 buffer 中,例如,写到一个指定的位置,或者把字节数组写入到 Buffer . 3、flip() 方法 flip 方法将 Buffer 从写模式切换到读模式。调用 flip() 方法将会 position 设置为 0 , 并且将 limt 设置为之前 position 的值。换句话说,position 现在用于标记读的位置,limit 表示之前写进了多少个 byte, char 等(现在能读取多少个 byte, char 等)。 六、从 Buffer 中读取数据 从 Buffer 中读取数据到 Channel 中: (1) 从 Buffer 中读取数据到 Channel (2)使用 get 方法从 Buffer 中读取数据 从 Buffer 中读取数据到 Channnel 到例子: // read form buffer into channel int bytesWritten = inChannel.write(buf); 使用 get() 方法从 Buffer 中读取数据的例子: byte aByte = buf.get(); get 方法中有很多版本,允许你以不同的方式 Buffer 中读取数据。例如,从指定 position 读取,或者从 Buffer 中读取到字节数组。 七、Buffer 几个方法1、rewind() 方法 Buffer.rewind() 将 position 返回0, 所以你可以重读 Buffer 中的所有数据。limit 保持不变,仍然表示能从 Buffer 中读取到多少个元素(byte, char 等)。 2、clear() 与 compact() 方法 一旦读完 Buffer 中的数据,需要让 Buffer 准备好再次被写入。可以通过 clear() 或 compact() 方法来完成 如果调用的是 cleanr () 方法,position 兼备设置为 0 , limit 被设置成 capactiy 的值。换句话说,Buffer 被清空了。 Buffer 中的数据并未清除,只是这些标记高数我们从哪里开始往 Buffer 中写数据。 如果 Buffer 中有些数未读的数据,调用 clear() 方法,数据将 "被遗忘",意味着不在有任何标记会告诉你那些数据被读过,那些还没有。 如果 Buffer 中依然有未读的数据,且后续还需要这些数据,但是此时想要先写这些数据,那么使用 compact() 方法。 compact() 方法将所有未读的数据拷贝到 Buffer 起始处。然后将 position 设置到最后一个未读元素正后面。 limit 属性依然像 clear() 方法一样。设置成 capacity. 现在 Buffer 准备好写数据了,但是不会覆盖未读的数据。 3、mark() 与 reset() 方法 通过调用 Buffer.mark() 方法,可以标记 Buffer 中的一个特定 position . 之后可以通过调用 Buffer.reset() 方法恢复到这个 position 例如: buffer.mark();// call buffer.get() a couple of times, e.g. during parsing buffer.reset(); // set position back to mark八、缓冲区操作1、缓冲区分片 在 NIO 中除了可以分配或者包装一个缓冲区对象外,还可以更具现有的缓冲区对象来创建一个子缓冲区,即现有缓冲区上切出一片来作为一个新的缓冲区,但现有的缓冲区与创建的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区相当于是现有缓冲区的一个视图窗口。调用 slice() 方法可以创建一个子缓冲区。 // 缓冲区分片@Testpublic void b01() { ByteBuffer buffer = ByteBuffer.allocate(10); // 放入数据 for (int i = 0; i < buffer.capacity(); i++) { buffer.put((byte) i); } // 创建子缓冲区 buffer.position(3); buffer.limit(7); ByteBuffer slice = buffer.slice(); // 改变子缓冲区中的内容 for (int i = 0; i < slice.capacity(); i++) { byte b = slice.get(i); b *= 10; slice.put(i, b); } // 复位 buffer.position(0); buffer.limit(buffer.capacity()); while (buffer.remaining() >

0) {System.out.println (buffer.get ());}}

The output is as follows:

2. Read-only buffer

Read-only buffers are so simple that you can read them, but you cannot write data to them. You can convert any regular buffer to a read-only buffer by calling the buffer's asReadOnlyBufer () method, which returns exactly the same buffer as the original buffer and shares data with the original buffer, except that it is read-only. If the contents of the original buffer change, the contents of the read-only buffer change accordingly:

/ / read-only buffer @ Testpublic void b02 () {ByteBuffer buffer = ByteBuffer.allocate (10); / / put data for (int I = 0; I)

< buffer.capacity(); i++) { buffer.put((byte) i); } // 创建一个只读缓冲区 ByteBuffer readOnlyBuf = buffer.asReadOnlyBuffer(); for (int i = 0; i < buffer.capacity(); i++) { byte b = buffer.get(i); b *= 10; buffer.put(i, b); } readOnlyBuf.position(0); readOnlyBuf.limit(readOnlyBuf.capacity()); while (readOnlyBuf.remaining() >

0) {System.out.println (readOnlyBuf.get ());}} 3, direct buffer

Direct buffer A buffer for which memory is allocated in a special way in order to speed up the speed of JDK O, the JDK document describes that given a direct byte buffer, the Java virtual machine will do its best to perform a native IAccord O operation on it directly before (or after) trying to avoid copying the contents of the buffer into an intermediate buffer or copying data from an intermediate buffer. To allocate a direct buffer, you need to call the allocatieDirect () method instead of the alloacte () method, which is used in the same way as a normal buffer.

/ / Direct buffer, file copy @ Testpublic void b03 () throws IOException {String filePath = "/ xx/01.txt"; FileInputStream inputStream = new FileInputStream (filePath); FileChannel fileInChannel = inputStream.getChannel (); String outPath = "/ xx/02.txt"; FileOutputStream outputStream = new FileOutputStream (outPath); FileChannel fileOutChannel1 = outputStream.getChannel (); / / use allocateDirect instead of allocate ByteBuffer buffer = ByteBuffer.allocateDirect (1024) While (true) {buffer.clear (); int r = fileInChannel.read (buffer); if (r =-1) {break;} buffer.flip (); fileOutChannel1.write (buffer);} fileInChannel.close (); fileOutChannel1.close ();} 4, memory-mapped file Imax O

The memory-mapped file Imax O is a way to read and write file data, which can be much faster than regular stream-or channel-based Imax O. The memory mapping Icano is done by making the data in the file appear as the contents of the memory array, which at first sounds like the master is just to read the whole file into the contents, but in fact this is not the case. Generally speaking, only the parts of the file that are actually read or written are mapped to memory.

/ / memory mapping file iAccord O @ Testpublic void b04 () throws IOException {String filePath = "/ xxx/01.txt"; RandomAccessFile randomAccessFile = new RandomAccessFile (filePath, "rw"); FileChannel fileChannel = randomAccessFile.getChannel (); MappedByteBuffer mappedByteBuffer = fileChannel.map (FileChannel.MapMode.READ_WRITE, 0, 1024); mappedByteBuffer.put (0, (byte) 97); mappedByteBuffer.put (1023, (byte) 122); fileChannel.close () } these are all the contents of the article "what's the use of Buffer buffers in Java NIO?" Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report