NIO类库
NIO概述
从JDK1.4开始,引入了新的I/O类库,它们位于java.nio包中,其目的在于提高I/O的操作效率。nio是new io的缩写。
参考文章:NIO BIO AIO区别
java.nio包引入了四个关键的数据类型:
- Buffer:缓冲区,临时存放输入或输出数据。
- Charset:把具有Unicode字符串编码转换为其他字符编码,以及把其他字符编码转换为Unicode编码的功能。
- Channel:数据传输管道。能够把Buffer中的数据写到数据汇,或者把数据源的数据读到Buffer。NIO基于Channel和Buffer操作,数据总是从信道读取数据到缓冲区中,或者从缓冲区写入到信道中。
- Selector:支持异步I/O操作,也称为非阻塞I/O操作。Selector用于监听多个信道事件(比如链接打开,数据到达等)使得单线程可以监听多个数据的信道
缓冲器Buffer概述
数据输入和输出往往是比较耗时的操作。缓冲区从两个方面提高I/O的操作效率
- 减少实际的物理读写次数
- 缓冲区在创建时被分配内存,这块内存一直被重用,这可以减少动态分配和回收内存区域的次数
旧IO类库中的BufferInputStream BufferOutStream BufferReader BufferWriter在实现中都运用了缓冲区。新I/O包公开了Buffer API,使得程序可以直接控制和运用缓冲区
所有缓冲区都有以下属性。

- 容量:表示缓冲区可以保存多少数据。
- 极限:表示缓冲区的当前终点,不能对缓冲区中超过极限的数据进行读写操作。极限值是可以修改的,这有利于缓冲区的重用。
列如 假定容量为100的缓冲区已经填满了数据,接着程序在重用缓冲区时,仅仅将十个新的数据写入缓冲区,这样时可以将极限值设置为10,这样就不能访问先前的数据。
极限值是一个非负整数值,不应该大于容量值。
- 位置:表示缓冲区下一个读写单元的位置,每次读写缓冲区的数据时,都会改变该值,为下一次读写数据做准备。位置是一个非负整数值,不应该大于容量值。
以上三个属性的关系为 容量≥极限 ≥位置 ≥0
缓冲区提供了用于改变以上三个属性的方法。
clear()使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将极限设置为容量大小,将位置设置为 0。flip()使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将极限设置为当前位置,然后将位置设置为 0。rewind()使缓冲区为重新读取已包含的数据做好准备:它使极限保持不变,将位置设置为 0。
Channel概述
通过Channel用来连接缓冲区与数据源或数据汇。数据源的数据经过通道到达缓冲区,缓冲区的数据经过通道到达数据汇。
中文意思“通道”,表示IO源与目标打开的连接,类似于传统的“流”(通道与流的不同之处在于通道是双向的)。但是Channel不能直接访问数据,
Channel最重要的两个接口ReadableByteChannel和WritableByteChannel。ReadableByteChannel声明了read(ByteBuffer dst)方法,该方法把数据源的数据读入到指定的ByteBuffer缓冲区中。
FileChannel是Channel接口的实现类,代表与一个文件相连的通道FileChannel类没有提供公开的构造方法,因此客户程序不能用new语句来构造它的实例。
不过,在FileInputStream FileOutputStream类中提供了getChannel()方法,该方法返回相应的FileChannel对象。
字符编码Charset概述
Charset类的每个实例代表指定的字符编码类型,提供了以下用于编码转换的方法。(把Charset对象表示的字符编码简称为当前字符编码)
- public final ByteBuffer encode(String str)
把参数str指定的字符串转换为当前字符的编码,把转换后的当前字符编码存放在一个ByteBuffer对象中,并将其返回。
- public final ByteBuffer encode(CharBuffer cb)
把参数cb指定的字符缓冲区中的字符转换为当前字符的编码,把转换后的当前字符编码存放在一个ByteBuffer对象中,并将其返回。原先参数cb缓冲区内的字符使用Unicode编码。
- public final CharBuffer decode(ByteBuffer bb)
把参数指定的ByteBuffer中的当前字符编码转换为Unicode编码,把转换后的Unicode编码存放在一个CharBuffer对象中,将其返回。
Selector
1)多路复用器(Selector),他是NIO编程的基础,非常重要。多路复用器提供选择已经就绪的任务的能力。
2)简单说,就是Selector会不断地轮询注册在其上的通道(Channel),如果某个通道发生了读写操作,这个通道就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以取得就绪的Channel集合,从而进行后续的IO操作。
3)一个多路复用器(Selector)可以负责成千上万Channel通道,没有上限,这也是JDK使用了epoll代替了传统的select实现,获得连接句柄没有限制。这也就意味着我们只要一个线程负责Selector的轮询,就可以接入成千上万个客户端,这是JDK NIO库的巨大进步。
4)Selector线程就类似一个管理者(Master),管理了成千上万个管道,然后轮询那个管道的数据已经准备好,通知cpu执行IO的读取或写入操作。
5)Selector模式:当IO事件(管道)注册到选择器以后,selector会分配给每个管道一个key值,相当于标签。selector选择器是以轮询的方式进行查找注册的所有IO事件(管道),当我们的IO事件(管道)准备就绪后,select就会识别,会通过key值来找到相应的管道,进行相关的数据处理操作(从管道里读或写数据,写到我们的数据缓冲区中)。
利用FileChannel读写文件
public class FileChannelTester {
public static void main(String[] args) throws Exception {
final int size = 1024;
final String path = "D:\\test.txt";
//向文件中写数据
FileChannel fc = new FileOutputStream(path).getChannel();
fc.write(ByteBuffer.wrap("你好,".getBytes()));
fc.close();
//向文件末尾添加数据
fc= new RandomAccessFile(path,"rw").getChannel();
fc.position(fc.size());
fc.write(ByteBuffer.wrap("朋友!".getBytes()));
fc.close();
//读数据
fc = new FileInputStream(path).getChannel();
ByteBuffer buff = ByteBuffer.allocate(size);
fc.read(buff);
buff.flip();
Charset cs = Charset.defaultCharset();
System.out.println(cs.decode(buff));
fc.close();
}
}
- 在上面main()方法中,先从文件输出流中得到一个FileChannel对象,然后通过它把ByteBuffer对象中的数据写到文件中。
"你好,".getBytes()使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。ByteBuffer类的wrap(byte[])把一个字节数组包装成一个ByteBuffer对象。
- main()方法接着从RandomAccessFile对象中得到一个FileChannel对象,定位到文件末尾,然后向文件中写入字符串"朋友!",该字符串仍然采用本地平台的字符编码。
- main()方法接着从文件输入了中得到一个FileChannel对象,然后调用ByteBuffer.allocate()方法创建了一个ByteBuffer对象 容量为1024个字节。
fc.read(buff)方法把文件中的数据读入到ByteBuffer中。接下来buff.flip()方法把缓冲区的极限limit设置为当前位置,
在把position设为0,这使得接下来的cs.decode(buff)方法仅仅操作刚刚写入缓冲区的数据。cs.decode()方法把缓冲区的数据转换为Unicode编码,然后打印该编码所代表的字符串。以上程序打印结果为"你好,朋友!"
NIO类库的更多相关文章
- Java NIO类库Selector机制解析(上)
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- Java NIO类库Selector机制解析--转
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- JAVA NIO 类库的异步通信框架netty和mina
Netty 和 Mina 我究竟该选择哪个? 根据我的经验,无论选择哪个,都是个正确的选择.两者各有千秋,Netty 在内存管理方面更胜一筹,综合性能也更优.但是,API 变更的管理和兼容性做的不是太 ...
- Java NIO类库Selector机制解析(下)
五. 迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/O要设计成这个样子?如果说老的I/O不能多路复用,如下图所示,要开N多的线程去挨个侦听每一个Channel ...
- NIO初识
Java编程中的NIO,俗称new I/O,是在JDK1.4版本之后开始引入的,在JDK1.4之前,Java服务端大多使用同步阻塞式来处理网络请求,在低流量.低并发情况还能抗住,在如今互联网时代,信息 ...
- 第二章 NIO入门
传统的同步阻塞式I/O编程 基于NIO的非阻塞编程 基于NIO2.0的异步非阻塞(AIO)编程 为什么要使用NIO编程 为什么选择Netty 第二章 NIO 入门 2.1 传统的BIO编程 2.1.1 ...
- Java NIO 基础
Java在JDK1.4中引入了 java.nio 类库,为Java进军后端Server和中间件开发打开了方便之门. 一般而言,这里的 nio 代表的是 New I/O,但是从实质上来说,我们可以将其理 ...
- JDK NIO编程
我们首先需要澄清一个概念:NIO到底是什么的简称?有人称之为New I/O,因为它相对于之前的I/O类库是新增的,所以被称为New I/O,这是它的官方叫法.但是,由于之前老的I/O类库是阻塞I/O, ...
- Java NIO服务器端开发
一.NIO类库简介 1.缓冲区Buffer Buffer是一个对象,包含一些要写入和读出的数据. 在NIO中,所有的数据都是用缓冲区处理的,读取数据时,它是从通道(Channel)直接读到缓冲区中,在 ...
随机推荐
- 在servlet中使用spring注解
@Autowired IAgreementPayService agreementPayService; /** * 支付参数 */ @Value("B{agreementPay.publi ...
- centos下设置开机启动程序
首先,设置权限, 由于/etc/rc.local是/etc/rc.d/rc.local的软连接,所以必须确保/etc/rc.local和/etc/rc.d/rc.local都有x权限(可执行) 执行命 ...
- python的学习之路(一)
1.python的简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为AB ...
- python 集合去重
data = set() data.clear() data.add('qq1') data.add('qq2') data.add('qq3') data.add('qq4') data.add(' ...
- C#生成COM组件
1.类库代码 1.1暴露的方法必须以接口的方式实现 1.2类需要GUID编号 using System; using System.Runtime.InteropServices; //COM组件 n ...
- 从分布式一致性到共识机制(二)Raft算法
春秋五霸说开 春秋五霸,是指东周春秋时期相继称霸主的五个诸侯,“霸”,意为霸主,即是诸侯之领袖.典型的比如齐桓公,晋文公,春秋时期诸侯国的称霸,与今天要讨论的Raft算法很像. 一.更加直观的Raft ...
- eclipse 开发环境问题
1.jdk安装,环境变量设置.主要有两个: JAVA_HOME C:\Program Files\Java\jre7 JRE_HOME C:\Program Files\Java\jre7 2 ...
- CentOS系统下搭建tomcat服务器
下载相应的linux版jdk和tomcat,本文讲解jdk版本jdk-7u79-linux-x64.tar.gz,tomcat版本apache-tomcat-7.0.69.tar.gz [配置jdk] ...
- numpy库补充 mean函数应用
mean()函数功能:求取均值经常操作的参数为axis,以m * n矩阵举例: axis 不设置值,对 m*n 个数求均值,返回一个实数 axis = 0:压缩行,对各列求均值,返回 1* n 矩阵 ...
- CICD - Teamcity 配置之一: 数据库自动部署
数据库开发过程不是一次完成的,也是一个迭代的过程.如何快速开发和部署新的数据库对象,部署到不同的环境中,还有就是可不可以快速重建数据库对象,这里不包括数据部分. 首先从官网下载Teamcity:htt ...