前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第十一节 netty前传-NIO 和IO对比

第十一节 netty前传-NIO 和IO对比

作者头像
用户1418372
发布2018-12-05 14:32:49
4320
发布2018-12-05 14:32:49
举报
文章被收录于专栏:清晨我上码清晨我上码

NIO和IO的区别

两者有两点最明显也是最主要的区别 IO:面向流、阻塞模式 NIO:面向缓冲、非阻塞模式

  • 对于第一点

第一个重要区别是IO是面向流的,NIO是面向缓冲区的。

面向流的Java IO意味着可以从流中一次读取一个或多个字节。 至于用读取字节做什么取决于客户。 它们不会缓存在任何地方。 此外,你无法在流中的数据中前后移动。 如果需要在从流中读取的数据中前后移动,则需要先将其缓存在缓冲区中。

Java NIO的面向缓冲区的方法略有不同。 将数据读入缓冲区,稍后处理该缓冲区。 客户可以根据需要在缓冲区中前后移动。 这使得在处理过程中更具灵活性。 但是,还需要检查缓冲区是否包含完整处理所需的所有数据。 并且,需要确保在将更多数据读入缓冲区时,不要覆盖尚未处理的缓冲区中的数据。

  • 对于第二点

第二个区别其实和和第一个也有很大关系。java io面向流,这就使得在从流中读写数据都是阻塞进行,而Java NIO一方面通过Selectors选择器允许单个线程监视多个输入通道。 也可以使用选择器注册多个通道,然后使用单个线程“select”已经准备好的通道。 这种选择器机制使单个线程可以轻松管理多个通道,另一方面面向缓冲使得java nio的读写可以立刻返回(非阻塞)。

相较而言java nio比java io更高效,但同时使用也更为复杂,比如下面例子

我的F:\book下有个a.txt内容如下

aaa bbb ccc

  • 在使用java io模式读取时
代码语言:javascript
复制
File file=new File("F:\\book\\a.text");
//获取输入流
InputStream input = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
//逐行读取
String a = reader.readLine();
String b = reader.readLine();
String c = reader.readLine();
  • 注意上面得io读取,因为时阻塞,所以一旦reader.readLine()方法返回,就确定已经读取了这一行得文本,如果nio中,非阻塞读取结果可能,下面java nio的实现方式
代码语言:javascript
复制
ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buffer);
  • 注意: 在第二行从channel读取字节到ByteBuffer。 当该方法调用返回时,我们并不知道所需的所有数据是否都在缓冲区内。 只知道缓冲区包含一些字节。 所以这种情况下设计nio模式的就会比较复杂,借用之前的部分代码片段如下:
代码语言:javascript
复制
ByteBuffer buffer = ByteBuffer.allocate(48);
 //注意:这个方法会记录读取的位置,所以后续读取不会从头开始读取
            int bytesRead = fileChannel.read(buffer);
            System.out.println(bytesRead);
            //读取到数据
            while(bytesRead != -1)
            {
                //反转后为可以读取缓冲中的数据
                buf.flip();
                while(buf.hasRemaining())//position < limit;表示可读
                {
                    //读取
                    System.out.print((char)buf.get());
                }
                //没有可读数据后,清除已读数据,从未读数据之后开始写入
                buf.compact();
                //开始继续读取
                bytesRead = fileChannel.read(buf);
            }

上面的代码也可简化入下图:

图片.png


也是由于nio的非阻塞和选择器这种特点,可以使得一个单线程管理多个通道,同时还可以让每一个通道使用单独的线程处理业务逻辑 简化如下:

图片.png

最后java并发包的设计者Doug Lea 有一篇关于nio的设计,我会在后续补上

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.11.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NIO和IO的区别
  • 最后java并发包的设计者Doug Lea 有一篇关于nio的设计,我会在后续补上
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档