Netty学习之NIO

NIO

如何生成IntBuffer

IntBuffer in = IntBuffer.allocate(10);

核心概念

A buffer is a linear, finite sequence of elements of a specific
primitive type. Aside from its content, the essential properties of a
buffer are its capacity, limit, and position:
缓冲区是由特定元素组成的线性、有限序列
原始类型。除了它的内容,a的基本属性
缓冲区是它的容量,限制和位置:

  • position

A buffer’s position is the index of the next element to be
read or written. A buffer’s position is never negative and is never
greater than its limit.

缓冲区的位置是下一个要访问的元素的索引
读或写。缓冲区的位置永远不会为负,也永远不会
大于它的极限。

  • limit

A buffer’s limit is the index of the first element that should
not be read or written. A buffer’s limit is never negative and is never greater than its capacity.
一个缓冲区的limit是第一个应该的元素的索引
不能读或写。缓冲区的极限永远不会为负,也永远不会为负
大于其容量。

  • capacity

A buffer’s capacity is the number of elements it contains. The
capacity of a buffer is never negative and never changes.
一个缓冲区的容量是它包含的元素的数量。的
缓冲区的容量永远不会是负的,也永远不会改变。

0
1
2
3

第一次:
0 就是position
3 就是capacity 指向
3 也是limit 指向

第二次写入数据AB
2 就是position
3 就是capacity 指向
2 也是limit 指向
第三次读数据AB
0 就是position
3 就是capacity 指向
2 也是limit 指向

0 A
1 B
2
3
  • Transferring data

Relative operations read or write one or more elements starting
at the current position and then increment the position by the number of
elements transferred. If the requested transfer exceeds the limit then a
relative get operation throws a {@link BufferUnderflowException}
and a relative put operation throws a {@link
BufferOverflowException}; in either case, no data is transferred
相对操作从一个或多个元素开始读写
在当前位置,然后将位置的值增加
元素转移。如果请求的转移超过限制,然后
相对的get操作抛出一个{@link BufferUnderflowException}
一个相对的put操作抛出一个{@link
BufferOverflowException};在这两种情况下,都不会传输数据

Absolute operations take an explicit element index and do not affect
the position. Absolute get and put operations throw an {@link
IndexOutOfBoundsException} if the index argument exceeds the limit.
绝对操作需要显式的元素索引,不需要 影响的位置。绝对的get和put操作抛出 一个{@link
IndexOutOfBoundsException}如果索引参数超过 极限。

  • Marking and resetting

A buffer’s mark is the index to which its position will be reset
when the {@link #reset reset} method is invoked. The mark is not always
defined, but when it is defined it is never negative and is never greater
than the position. If the mark is defined then it is discarded when the
position or the limit is adjusted to a value smaller than the mark. If the
mark is not defined then invoking the {@link #reset reset} method causes an
{@link InvalidMarkException} to be thrown.
缓冲区的标记是其位置将被重置的索引
当调用{@link #reset reset}方法时。标记并不总是
它是有定义的,但当它被定义时,它就不会是负的,也不会更大
比这个职位。如果标记被定义,那么当
位置或限制被调整到一个比标记小的值。如果
如果没有定义mark,那么调用{@link #reset reset}方法将导致
{@link InvalidMarkException}被抛出。

  • Invariants

The following invariant holds for the mark, position, limit, and
capacity values:

0 <= mark <= position <= limit<= capacity

大小关系为: 0 <= mark <= position <= limit <= capacity

A newly-created buffer always has a position of zero and a mark that
is undefined. The initial limit may be zero, or it may be some other
value that depends upon the type of the buffer and the manner in
which it is constructed. Each element of a newly-allocated buffer is
initialized to zero. 新创建的缓冲区总是有一个位置为0的标记 未定义的。初始极限可以是零,也可以是其他值
这取决于缓冲区的类型和方式 构造。新分配的缓冲区的每个元素都被初始化 为零。

  • Clearing, flipping, and rewinding
clear

makes a buffer ready for a new sequence of channel-read or relative put operations: It sets the limit to the capacity and the position to zero.
使缓冲区为新的序列做好准备
channel-read或相对的put操作:它设置了对容量和位置为零。

flip

makes a buffer ready for a new sequence of
channel-write or relative get operations: It sets the limit to the
current position and then sets the position to zero.
使缓冲区为新的序列做好准备
channel-write或相对get操作:它设置对
当前位置,然后将位置设置为零。

rewind

makes a buffer ready for re-reading the data that it already contains: It leaves the limit unchanged and sets the position to zero.
使缓冲区准备好重新读取它已经包含的数据:它保持限制不变并将位置设置为0。

  • Read-only buffers
  • Thread safety (高并发下线程不是安全的)
  • Invocation chaining(链式调用)

例如 in.flip().clear().rewind();

案例测试理论

package org.cloud_common.netty.nio;

import cn.hutool.core.lang.Console;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;
import java.security.SecureRandom;

/**
 * @ClassName NioTest
 * @Description: TODO
 * @Author drj
 * @Date 2021/1/26
 * @Version V1.0
 **/
public class NioTest {
    
    

    public static void main(String[] args) throws  Exception{
    
    
        IntBuffer in = IntBuffer.allocate(4);
        Console.log("初始化容量:{},限制:{},位置:{}",in.capacity(),in.limit(),in.position());
        for (int i=0; i < 2; i++){
    
    
            int r = new SecureRandom().nextInt(20);
            in.put(r);
        }
        Console.log("flip前容量:{},限制:{},位置:{}",in.capacity(),in.limit(),in.position());
       in.flip();
        Console.log("flip后容量:{},限制:{},位置:{}",in.capacity(),in.limit(),in.position());
        while (in.hasRemaining()){
    
    
            cn.hutool.core.lang.Console.log("数据:{},容量:{},限制:{},位置:{}",in.get(),in.capacity(),in.limit(),in.position());
        }
    }
  • 输出如下

初始化容量:4,限制:4,位置:0
flip前容量:4,限制:4,位置:2
flip后容量:4,限制:2,位置:0
数据:1,容量:4,限制:2,位置:1
数据:6,容量:4,限制:2,位置:2

猜你喜欢

转载自blog.csdn.net/qq_29897369/article/details/113438258