1起点JAVANIOBuffer中各种重要的状态属性的含义与关系图解

一个简单的NIO例子

   FileOutputStream outputStream = new FileOutputStream("NioTest3.txt");
        FileChannel channel = outputStream.getChannel();
		//穿件一个512 大小的buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(512);

        byte[] bytes = "hello wolr  jian geg  wo ai ni ".getBytes();

        for (int i = 0; i < bytes.length; i++) {
            byteBuffer.put(bytes[i]);
        }

        byteBuffer.flip();
        channel.write(byteBuffer);
        outputStream.close();
    }
//这个方法是我们在NIO中必须要用到的东西 
//读写切换必须要用方法 ,写数据 状态的翻转读写的切换
  byteBuffer.flip();

NIO的基本概念与笔记

Io中最核心的一个概念为流(Stream),面向流的编程,是信息的载体。通过流获取到相关信息,要么是输入流 ,要么是输出流,一个流要么是输入流, 要么是输出流 不可同时既是输入流,又是输出流  直接读
在NIo中 3个概念 Selector选择器, Channel ,Buffer 在nio 中我们是面向block 块 和面向buffer 缓冲的 buffer本身就是一块内存 底层实现上就是一个数组,数据的读和谐都是操作数组来实现的,一个缓冲区既可以读和写 先读到buffer 中 也可以写到buffer 中,不仅可以读还可以写 @flip 方法 切换读写的状态的 
除了数组之外,buffer 还一共了对于数据的结构化访问方式,并且可以追踪到系统的读写过程 
Java 中8中原声数据类型都由各自对应这buffer 类型 int char bytybuffer  

NIO基本流程图

示意图:一个线程对用这一个Selector  一个selector 对应3个channel一个channel 对应这一个buffer 

一个线程可以在这三个channel上面来回切换, 具体某一个时刻切换到哪儿 是由event 来决定的 event 通过event来判断当前selector 在哪儿

Event 时间的判断  NIO 里面的Channel 可以理解为IO 中的Stream 

Buffer 本身就是一块内存,底层实现上 它实际上就是一个数组 

数据的读与写都是通过 BUffer来操作的  数据的读与写都是Buffer来操作的  
FileChannel  数据从Channel读取到Buffer里面 在读取到程序中 

Channel是双向的所以他能更好的反映出底层操作系统的真实情况  

源码看一看大概的意思与 问题 :buffer是怎么读?怎么写?flip()方法执行的原理:

那么它的原理是什么样子的呢?源码分析 :
关于NIO BUffer中的重要的三个属性的含义 :postiton,limit与capacity
在JavaDoc里面有这么一句话

Aside from its content, the essential properties of a
* buffer are its capacity, limit, and position:(buffer的本质就是capacity,limit,和position) 
* capacity容量,position限制,limit位置
capacity 也就是我们初始化的大小,它不会改变 分配好之后就永远不会改变 ByteBuffer.allocate(512); 这样里面就是capacity大小就是512  

 <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
*   capacity of a buffer is never negative and never changes.  </p>
*
*   <p> A buffer's <i>limit</i> 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.  </p>
*
*   <p> A buffer's <i>position</i> 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.  </p>

如图: 我们创建一个大小为6的buffer 那么它得 capacity 也就是为 6
因为我们的索引是从0开始的 所以 它得capacity 值也就指向了最后一个元素的下一个元素
那么它的limit 也是指向了 6
大致过程:
在这里插入图片描述
p代表position ,

Buffer类简单了解

Buffer的类型
direct buffers 创建在堆中的内存,拷贝的时候实现方式是0拷贝的,直接缓存
一种是普通的Buffer

代码测试

 public static void main(String[] args) {
        //将整数生成一个并且随机的
        IntBuffer buffer = IntBuffer.allocate(10);

        for (int i = 0; i < 5; ++i) {
            //生成一个随机数
            int randomNumber = new SecureRandom().nextInt(20);
            buffer.put(randomNumber);
        }
        //输出 10
        System.out.println("before flip limit" + buffer.limit());
        //写数据 状态的翻转读写的切换
        buffer.flip();
        //翻转完之后的打印
        System.out.println("after flip limit" + buffer.limit());
        //读数据
        while (buffer.hasRemaining()) {
            System.out.println("position" + buffer.position());
            System.out.println("limit" + buffer.limit());
            System.out.println("capacity" + buffer.capacity());
            System.out.println(buffer.get());
        }
    }

result

before flip limit10
after flip limit5
进入到While循环.....
position0
limit5
capacity10
获取到的随机数:12
position1
limit5
capacity10
获取到的随机数:1
position2
limit5
capacity10
获取到的随机数:8
position3
limit5
capacity10
获取到的随机数:4
position4
limit5
capacity10
获取到的随机数:0

Process finished with exit code 0

结果分析参照画的图图

操作File文件的示例

public static void main(String[] args) throws Exception {
        FileInputStream inputStream = new FileInputStream("input.txt");
        FileOutputStream outputStream = new FileOutputStream("output.txt");

        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outputChannel = outputStream.getChannel();

        ByteBuffer buffer = ByteBuffer.allocate(512);
        while (true) {
            //这个Clear 方法必须添加 要不然它会一直写文件到Out.txt中
            buffer.clear();

            int read = inputChannel.read(buffer);
            System.out.println("read ::" + read);
            if (-1 == read) {
                break;
            }
            buffer.flip();

            outputChannel.write(buffer);
        }
        inputChannel.close();
        outputChannel.close();
    }

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值