1. 什么是NIO

NIO是New I/O的简称,与旧式的基于流的I/O方法相对,从名字看,它表示新的一套Java I/O标 准。它是在Java 1.4中被纳入到JDK中的,并具有以下特性:

  • NIO是基于块(Block)的,它以块为基本单位处理数据 (硬盘上存储的单位也是按Block来存储,这样性能上比基于流的方式要好一些)

  • 为所有的原始类型提供(Buffer)缓存支持

  • 增加通道(Channel)对象,作为新的原始 I/O 抽象

  • 支持锁(我们在平时使用时经常能看到会出现一些.lock的文件,这说明有线程正在使用这把锁,当线程释放锁时,会把这个文件删除掉,这样其他线程才能继续拿到这把锁)和内存映射文件的文件访问接口

  • 提供了基于Selector的异步网络I/O

所有的从通道中的读写操作,都要经过Buffer,而通道就是io的抽象,通道的另一端就是操纵的文件。

2. Buffer

Java中Buffer的实现。基本的数据类型都有它对应的Buffer

Buffer的简单使用例子:

public class Test {
public static void main(String[] args) throws Exception { FileInputStream fin = new FileInputStream(new File("d:\\buffer.tmp")); FileChannel fc = fin.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); fc.read(byteBuffer); fc.close(); byteBuffer.flip();//读写转换 } }

总结下使用的步骤是:

1. 得到Channel

2. 申请Buffer

3. 建立Channel和Buffer的读/写关系

4. 关闭

下面的例子是使用NIO来复制文件:

public static void nioCopyFile(String resource, String destination)
throws IOException {
FileInputStream fis = new FileInputStream(resource);
FileOutputStream fos = new FileOutputStream(destination);
FileChannel readChannel = fis.getChannel(); // 读文件通道
FileChannel writeChannel = fos.getChannel(); // 写文件通道
ByteBuffer buffer = ByteBuffer.allocate(1024); // 读入数据缓存
while (true) {
buffer.clear();
int len = readChannel.read(buffer); // 读入数据
if (len == -1) {
break; // 读取完毕
}
buffer.flip();
writeChannel.write(buffer); // 写入文件
}
readChannel.close();
writeChannel.close();
}

Buffer中有3个重要的参数:位置(position)、容量(capactiy)和上限(limit)

这里要区别下容量和上限,比如一个Buffer有10KB,那么10KB就是容量,我将5KB的文件读到Buffer中,那么上限就是5KB。

Buffer中大多数的方法都是去改变这3个参数来达到某些功能的:

public final Buffer rewind()     将position置零,并清除标志位(mark)

public final Buffer clear()        将position置零,同时将limit设置为capacity的大小,并清除了标志mark

public final Buffer flip()           先将limit设置到position所在位置,然后将position置零,并清除标志位mark,通常在读写转换时使用

文件映射到内存

public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("C:\\mapfile.txt", "rw");
FileChannel fc = raf.getChannel();
// 将文件映射到内存中
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0,
raf.length());
while (mbb.hasRemaining()) {
System.out.print((char) mbb.get());
}
mbb.put(0, (byte) 98); // 修改文件
raf.close();
}

3. Channel

Channel有点类似于流,一个Channel可以和文件或者网络Socket对应。

selector是一个选择器,它可以选择某一个Channel,然后做些事情。

一个线程可以对应一个selector,而一个selector可以轮询多个Channel,而每个Channel对应了一个Socket。

当selector调用select()时,会查看是否有客户端准备好了数据。当没有数据被准备好时,select()会阻塞。

selectNow()与select()的区别在于,selectNow()是不阻塞的,当没有客户端准备好数据时,selectNow()不会阻塞,将返回0,有客户端准备好数据时,selectNow()返回准备好的客户端的个数。平时都说NIO是非阻塞的,但是如果没有数据被准备好还是会有阻塞现象。

当有数据被准备好时,调用完select()后,会返回一个SelectionKey,SelectionKey表示在某个selector上的某个Channel的数据已经被准备好了。

只有在数据准备好时,这个Channel才会被选择。

这样NIO实现了一个线程来监控多个客户端。

NIO和AIO的区别和总结

nio:

1. NIO会将数据准备好后,再交由应用进行处理,数据的读取/写入过程依然在应用线程中完成,只是将等待的时间剥离到单独的线程中去。

2. 节省数据准备时间(因为Selector可以复用)

aio:

1. 读完了再通知我(内核内存拷贝到工作内存到过程)

2. 不会加快IO,只是在读完后进行通知

3. 使用回调函数,进行业务处理

NIO是同步非阻塞的

AIO是异步非阻塞的

由于NIO的读写过程依然在应用线程里完成,所以对于那些读写过程时间长的,NIO就不太适合。

而AIO的读写过程完成后才被通知,所以AIO能够胜任那些重量级,读写过程长的任务。

java的NIO和AIO的更多相关文章

  1. Java BIO NIO 与 AIO

    回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...

  2. Java之NIO,BIO,AIO

    Hollis知识星球的一些学习笔记,有兴趣的朋友可以微信搜一下 什么是NIO 什么是IO? 它是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键,因而所有 ...

  3. Java BIO、NIO、AIO 学习(转)

    转自 http://stevex.blog.51cto.com/4300375/1284437 先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Ja ...

  4. JAVA bio nio aio

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

  5. JAVA中IO技术:BIO、NIO、AIO

    1.同步异步.阻塞非阻塞概念        同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作 ...

  6. Java IO 之 BIO、NIO、AIO

    1.BIO.NIO.AIO解释 Java BIO : 同步并阻塞 (Blocking IO) 一个连接一个线程 即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不 ...

  7. Java提高班(五)深入理解BIO、NIO、AIO

    导读:本文你将获取到:同/异步 + 阻/非阻塞的性能区别:BIO.NIO.AIO 的区别:理解和实现 NIO 操作 Socket 时的多路复用:同时掌握 IO 最底层最核心的操作技巧. BIO.NIO ...

  8. Java IO、NIO、AIO知识总结

    本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到. 本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助. https://www.cnblogs.com/ ...

  9. Java的BIO,NIO和AIO的区别于演进

    作者:公众号:我是攻城师 前言 Java里面的IO模型种类较多,主要包括BIO,NIO和AIO,每个IO模型都有不一样的地方,那么这些IO模型是如何演变呢,底层的原理又是怎样的呢? 本文我们就来聊聊. ...

随机推荐

  1. HDU1253 胜利大逃亡(BFS) 2016-07-24 13:41 67人阅读 评论(0) 收藏

    胜利大逃亡 Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示 ...

  2. hdu1302 The Snail

    题目 题目大意: 一只蜗牛在H英尺高的底部,想爬到顶端.蜗牛可以在太阳升起的时候爬上U英尺,但是在晚上睡觉的时候会滑下D英尺.蜗牛的疲劳系数为F(百分比),                       ...

  3. Python2.7升级至Python3.6

    Python2.7升级至Python3.6 今天在CentOS7.2上将python2.7升级至python3.6时遇到了诸多问题,下面将升级步骤以及解决方法一一列举. 1.安装Python3.6 安 ...

  4. [翻译]NUnit---TestCase Attributes(二十一)

    TestCaseAttribute (NUnit 2.5) TestCase特性有两个效果,包括标记一个方法使用参数并且在调用的时候提供内置数据.示例如下,本示例会使用不同数据集执行3次: [Test ...

  5. Windows Server 2012 R2部署--安装桌面体验

    Windows Server 2012 R2部署(3)---安装桌面体验 1) 打开服务器管理器 2) 选择所有服务器    3)添加角色和功能    4)下一步    5)下一步    6)下一步 ...

  6. westrac server security configure user info

    security userkey:westracpass:Set#@!123

  7. Day14 作业

    1,整理今天的博客,写课上代码,整理流程图. 2,用列表推导式做下列小题 (1)   过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 (2)   求(x,y)其中x是0-5之间的偶数,y是0- ...

  8. 使用pipreqs生成项目依赖

    作用 导出当前项目的环境依赖 使用 # 安装 pip3 install pipreqs # 导出项目环境依赖 pipreqs ./ # 如果是Windows系统,会报编码错误 (UnicodeDeco ...

  9. python 利用from ... import * 的特性实现文件的覆盖

    在Python中, 如果使用 from module import * 这样方式进行导包, 就会把module模块里所有的变量导入进来, 并且可以直接使用(其实导包时 module 模块已经被从头到尾 ...

  10. hdu4815----dp0-1背包

    /* 题目大意: 有n个问题,,告诉你答对该题能得多少分,其中一个人随机答题,问另一个人不输的概率为p 至少需要答多多少分 对于样例: 3 0.5 1 2 3 分析: 分数 0 1 2 3 3 4 5 ...