栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【肝货】NIO缓冲流(持续更新)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【肝货】NIO缓冲流(持续更新)

NIO缓冲流
    • IO流和NIO流
    • NIO介绍
        • nio核心
        • nio面向"块"
        • nio的非阻塞
        • NIO流程图
    • java.nio.ByteBuffer
      • Buffer参数说明
      • Buffer的常用方法:
      • 实例Demo

IO流和NIO流

基本区别:
传统IO是面向流的,NIO是面向缓冲的。传统IO是每次从流中读一个或多个字节,直到读取所有字节,它们没有被缓存在任何地方。
NIO是将数据读取到一个稍后处理的缓冲区,需要时可在缓冲区中前后移动,增加了处理过程中的灵活性。
IO与NIO的适用场景:
如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,实现NIO的服务器可能是一个优势。
如果你有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的IO服务器实现可能非常契合。
底层处理:
IO流是每次处理一个或多个字节。
NIO流是以数据块为单位来处理,缓冲区就是用于读写的数据块。

NIO介绍 nio核心

NIO 有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器) 。
Channel和Buffer:NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中
Selector:选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

nio面向"块"

NIO是 面向缓冲区 ,或者面向 块 编程的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络
(数据读取到缓冲区后可以前后移动的意思:详细理解下面缓冲区的参数说明和常用方法即可)

nio的非阻塞

Java NIO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。(同步异步阻塞非阻塞概念链接: link.)
举例:NIO是可以做到用一个线程来处理多个操作的。假设有10000个请求过来,根据实际情况,可以分配50或者100个线程来处理。不像之前的阻塞IO那样,非得分配10000个。

NIO流程图

java.nio.ByteBuffer Buffer参数说明

主要有五个属性:mark,position,limit,capacity和array
mark:记录了当前所标记的索引下标;
position:对于写入模式,表示当前可写入数据的下标,对于读取模式,表示接下来可以读取的数据的下标;
limit:对于写入模式,表示当前可以写入的数组大小,默认为数组的最大长度,对于读取模式,表示当前最多可以读取的数据的位置下标;
capacity:表示当前数组的容量大小;
array:保存了当前写入的数据。

Buffer的常用方法:

flip():确定缓冲区数据的起始点和终止点,为输出数据做准备(即写入通道)。此时:limit = position,position = 0。
clear():缓冲区初始化,准备再次接收新数据到缓冲区。position = 0,limit = capacity。
remaining():判断postion到limit之间是否还有元素。(查看源码该方法返回的就是 limit - position)
rewind():postion设为0,则mark值无效。
limit(int newLt):设置界限值,并返回一个缓冲区,该缓冲区的界限和limit()设置的一样。
get()和put():获取元素和存放元素。使用clear()之后,无法直接使用get()获取元素,需要使用get(int index)根据索引值来获取相应元素。

实例Demo
  //数据从通道读取到缓冲区中,也可以从缓冲区写入到通道中
             	ByteBuffer respHeader = ByteBuffer.allocate(8);//创建缓冲区,并初始化大小
                // 获取响应报文
                Socket client = new Socket();//创建通道
                InputStream is = client.getInputStream();
                byte[] tmpHeader = new byte[8];
                int length = 0;
                //is.read(tmpHeader) 数据从通道读取到缓存区
                while ((respHeader.remaining() != 0) && ((length = is.read(tmpHeader)) != -1)) {
                    respHeader.put(tmpHeader, 0, length);
                    tmpHeader = new byte[respHeader.remaining()];
                }
                respHeader.array();
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/590540.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号