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

Introduction to Java Buffer buffer (NIO) operation

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article mainly explains "Java Buffer (NIO) Operation Introduction", the explanation content in the article is simple and clear, easy to learn and understand, please follow the idea of Xiaobian slowly in-depth, together to study and learn "Java Buffer (NIO) Operation Introduction" bar!

directory

Java NIO(Buffer)

1.1 Buffer Profile

1.2 Basic Usage of Buffer

1. Use Buffer to read and write data, generally follow the following four steps:

Examples of using ByteBuffer

Examples of using IntBuffer

1.3 Buffer capacity, position and limit

(1)capacity

(2)position

(3)limit

1.4 Type of Buffer

1.5 Buffer allocation and write data

1. Buffer allocation

2. Write data to Buffer

Flip() method

1.6 Read data from Buffer

1.7 Buffer several ways

Rewind() method

clear() and compact() methods

Mark() and reset() methods

1.8 buffer operations

1. Buffer fragmentation

2. Read-only buffer

3. Direct buffer

Memory mapped file I/O

Java NIO (Buffer) 1.1 Buffer

Buffer in Java NIO is used to interact with NIO channels. Data is read from the channel into the buffer and written from the buffer into the channel.

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

A buffer is actually a container object, or more directly, an array. In NIO libraries, all data is processed in buffers.

When data is read, it is read directly into the buffer; when data is written, it is written into the buffer; and whenever data in NIO is accessed, it is placed into the buffer. In stream-oriented I/O systems, all data is written directly or read directly into Stream objects.

In NIO, all buffer types are inherited from the abstract class Buffer, the most commonly used is ByteBuffer, for the basic types in Java, there is basically a specific Buffer type corresponding to it, the inheritance relationship between them is shown in the following figure:

1.2 Buffer basic usage 1, using Buffer to read and write data, generally follow the following four steps:

(1) Write data to Buffer

(2) Call flip() method

(3) Reading data from Buffer

(4) Call clear() method or compact() method

When data is written to the buffer, the buffer keeps track of how much data has been written. Once you want to read data, you need to switch Buffer from write mode to read mode via 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 empty the buffer: call the clear() or compact() methods.

The clear() method empties the entire buffer.

The compact() method only clears data that has already been read.

Any unread data is moved to the beginning of the buffer, and newly written data is placed behind the unread data in the buffer.

@Testpublic void testConect2() throws IOException { RandomAccessFile aFile = new RandomAccessFile("d:\\achang/01.txt","rw"); FileChannel inChannel = aFile.getChannel(); //Create buffer and specify size (bytes) ByteBuffer buf = ByteBuffer.allocate (1024); int bytesRead = inChannel.read (buffer); //Read buffer while (bytesRead != -1) { buf.flip(); //read/write conversion, read mode while(buf.hasRemaining()){ System.out.print((char) buf.get()); // read 1 byte at a time } buffer f.clear(); //clear buffer //read operation bytesRead = inChannel.read(buf); } aFile.close();}3, Examples of using IntBuffer @Testpublic void testConect3() throws IOException { //Allocate a new int buffer with buffer size //The current position of the new buffer will be zero and its limit (limit position) will be its capacity. //It will have an underlying implementation array whose array offset will be zero. 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 + " "); }}1.3 Buffer 的 capacity、position 和 limit 为了理解 Buffer 的工作原理,需要熟悉它的三个属性: CapacityPositionlimit position 和 limit 的含义取决于 Buffer 处在读模式还是写模式。不管 Buffer 处在什么模式,capacity 的含义总是一样的。 这里有一个关于 capacity,position 和 limit 在读写模式中的说明 (1)capacity 作为一个内存块,Buffer 有一个固定的大小值,也叫"capacity". 你只能往里写capacity 个 byte、long,char 等类型。 一旦 Buffer 满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。 (2)position 写数据到 Buffer 中时,position 表示写入数据的当前位置,position 的初始值为0。 当一个 byte、long 等数据写到 Buffer 后, position 会向下移动到下一个可插入数据的 Buffer 单元。position 最大可为 capacity - 1(因为 position 的初始值为0). 读数据到 Buffer 中时,position 表示读入数据的当前位置,如 position=2 时表示已开始读入了 3 个 byte,或从第 3 个 byte 开始读取。 通过 ByteBuffer.flip()切换到读模式时 position 会被重置为 0,当 Buffer 从 position 读入数据后,position 会下移到下一个可读入的数据 Buffer 单元。 (3)limit 写数据时,limit 表示可对Buffer 最多写入多少个数据。写模式下,limit 等于Buffer 的 capacity。读数据时,limit 表示 Buffer 里有多少可读数据(not null 的数据),因此能读到之前写入的所有数据(limit 被设置成已写数据的数量,这个值在写模式下就是position)。(剩余未读的数据) 1.4 Buffer 的类型 Java NIO 有以下 Buffer 类型 ByteBufferMappedByteBufferCharBufferDoubleBufferFloatBufferIntBufferLongBufferShortBuffer 这些 Buffer 类型代表了不同的数据类型。 换句话说,就是可以通过 char,short,int,long,float 或 double 类型来操作缓冲区中的字节。 1.5 Buffer 分配和写数据1、Buffer 分配 要想获得一个 Buffer 对象首先要进行分配。 每一个 Buffer 类都有一个 allocate 方法。 下面是一个分配 48 字节 capacity 的 ByteBuffer 的例子。 ByteBuffer buf = ByteBuffer.allocate(48); 这是分配一个可存储 1024 个字符的 CharBuffer: CharBuffer buf = CharBuffer.allocate(1024);2、向 Buffer 中写数据 写数据到 Buffer 有两种方式: (1)从 Channel 写到 Buffer。 (2)通过 Buffer 的 put()方法写到 Buffer 里。 从 Channel 写到 Buffer 的例子 int bytesRead = inChannel.read(buf); //read into buffer. 通过 put 方法写 Buffer 的例子: buf.put(127); put 方法有很多版本,允许你以不同的方式把数据写入到 Buffer 中。例如, 写到一个指定的位置,或者把一个字节数组写入到 Buffer 3、flip()方法 flip 方法将 Buffer 从写模式切换到读模式。调用 flip()方法会将 position 设回 0,并将 limit 设置成之前 position 的值。 换句话说,position 现在用于标记读的位置,limit 表示之前写进了多少个 byte、char 等 (现在能读取多少个 byte、char 等)。 1.6 从 Buffer 中读取数据 从 Buffer 中读取数据有两种方式: (1)从 Buffer 读取数据到 Channel。 (2)使用 get()方法从 Buffer 中读取数据。 从 Buffer 读取数据到 Channel 的例子: //read from buffer into channel.int bytesWritten = inChannel.write(buf); 使用 get()方法从 Buffer 中读取数据的例子 byte aByte = buf.get(); get 方法有很多版本,允许你以不同的方式从 Buffer 中读取数据。例如,从指定position 读取,或者从 Buffer 中读取数据到字节数组。 1.7 Buffer 几个方法1、rewind()方法 Buffer.rewind()将 position 设回 0,所以你可以重读 Buffer 中的所有数据。limit 保持不变,仍然表示能从 Buffer 中读取多少个元素(byte、char 等)。 2、clear()与 compact()方法 一旦读完 Buffer 中的数据,需要让 Buffer 准备好再次被写入。可以通过 clear()或compact()方法来完成。 如果调用的是 clear()方法,position 将被设回 0,limit 被设置成 capacity 的值。换句话说,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.8、缓冲区操作1、缓冲区分片 在 NIO 中,除了可以分配或者包装一个缓冲区对象外,还可以根据现有的缓冲区对象来创建一个子缓冲区,即在现有缓冲区上切出一片来作为一个新的缓冲区,但现有的缓冲区与创建的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区相当于是现有缓冲区的一个视图窗口。调用 slice()方法可以创建一个子缓冲区。 @Testpublic void testConect3() throws IOException { ByteBuffer buffer = ByteBuffer.allocate (10); // 缓冲区中的数据 0-9 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()); }}

2. Read-only buffer

Read-only buffers are very simple; 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 asReadOnlyBuffer() method, which returns an identical 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 also change:

@Testpublic void testConect4() throws IOException { ByteBuffer buffer = ByteBuffer. allocate (10); //data in buffer 0-9 for (int i = 0; i

< buffer.capacity(); ++i) { buffer.put((byte) i); } // 创建只读缓冲区 ByteBuffer readonly = buffer.asReadOnlyBuffer(); // 改变原缓冲区的内容 for (int i = 0; i < buffer.capacity(); ++i) { byte b = buffer.get(i); b *= 10; buffer.put(i, b); } readonly.position(0); readonly.limit(buffer.capacity()); // 读取只读缓冲区的内容也随之改变 while (readonly.remaining() >

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

If you try to modify the contents of a read-only buffer, a ReadOnlyBufferException is reported.

Read-only buffers are useful for protecting data. When passing a buffer to a method of an object, there is no way of knowing whether the method modifies the data in the buffer. Creating a read-only buffer ensures that the buffer will not be modified.

You can only convert regular buffers to read-only buffers; you cannot convert read-only buffers to writable buffers.

3. Direct buffer

A direct buffer is a buffer for which memory is allocated in a special way to speed up I/O, as described in the JDK documentation: Given a direct byte buffer, the Java Virtual Machine will do its best to perform native I/O operations directly on it.

That is, it tries to avoid copying the contents of a buffer into or out of an intermediate buffer before (or after) every call to the underlying OS's native I/O operation. To allocate a direct buffer, you need to call the allocateDirect() method instead of the allocate() method, and use it in the same way as a normal buffer.

Copy file example:

@Testpublic void testConect5() throws IOException { //read String infile = "d:\\achang\\01.txt"; FileInputStream fin = new FileInputStream(infile); FileChannel fcin = fin.getChannel(); //Output String outfile = "d:\\achang\\02.txt"; FileOutputStream fout = new FileOutputStream(outfile); FileChannel fcout = fout.getChannel(); //use allocateDirect instead of allocate ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { buffer.clear(); int r = fcin.read(buffer); if (r == -1) { break; } buffer.flip();//Go to write mode fcout.write(buffer); Memory mapped file I/O

Memory-mapped file I/O is a method of reading and writing file data that can be much faster than conventional stream-based or channel-based I/O.

Memory-mapped file I/O is accomplished by making the data in the file appear as the contents of a memory array, which at first sounds like nothing more than reading the entire file into memory, but it's not. In general, only the parts of a file that are actually read or written are mapped to memory.

Sample code: MappedByteBuffer

static private final int start = 0;static private final int limit = 1024;static public void main(String args[]) throws Exception { RandomAccessFile raf = new RandomAccessFile("d:\\achang\\01.txt","rw"); FileChannel fc = raf.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE,start,limit); mbb.put(0,(byte) 97); mbb.put(1023, (byte) 122); raf.close();} Thank you for reading, the above is the "Java Buffer (NIO) operation introduction" content, after the study of this article, I believe that everyone on Java Buffer (NIO) operation introduction this problem has a deeper understanding, the specific use of the situation also needs to be verified by practice. Here is, Xiaobian will push more articles related to knowledge points for everyone, welcome to pay attention!

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