一、简介
1.IO和NIO的对比
(1)IO是面向流的,NIO是面向缓冲区的
Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方;
NIO则能前后移动流中的数据,因为是面向缓冲区的
(2)IO流是阻塞的,NIO流是不阻塞的
Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了
Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。NIO可让您只使用一个(或几个)单线程管理多个通道(网络连接或文件),但付出的代价是解析数据可能会比从一个阻塞流中读取数据更复杂。
非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。
(3)选择器
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
2.NIO
Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。
Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
|-----java.nio.channels.Channel
|-----FileChannel:处理本地文件
|-----SocketChannel:TCP网络编程的客户端的Channel
|-----ServerSocketChannel:TCP网络编程的服务器端的Channel
|-----DatagramChannel:UDP网络编程中发送端和接收端的Channel
3.NIO. 2
随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。 因为 NIO 提供的一些功能,NIO已经成为文件处理中越来越重要的部分。
java.nio 提供了对于 NIO 系统支持的类库,该包的主要结构如下:
java.nio NIO系统的顶级包,NIO系统封装了各种类型的缓冲区;
java.nio.charset 封装了字符集,并且还支持分别将字符转换为字节和字节到编码器和解码器的操作;
java.nio.charset.spi 用于提供字符集服务;
java.nio.channels 用于支持通道,这些通道本质上是打开I/O连接;
java.nio.channels.spi 用于支持频道服务;
java.nio.file 用于提供对文件的支持;
java.nio.file.spi 用于提供支持文件系统的辅助服务;
java.nio.file.attribute 用于对文件属性提供的支持
二、核心API
1.Path、Paths类
早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所 提供的方法性能也不高。而且,大多数方法在出错时仅返回失败,并不会提供异 常信息。 NIO. 2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描 述了目录结构中文件的位置。Path可以看成是File类的升级版本,实际引用的资源也可以不存在。
在以前IO操作都是这样写的:
import java.io.File; File file = new File("index.html");
但在Java7 中,我们可以这样写:
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("index.html");
同时,NIO.2在java.nio.file包下还提供了Files、Paths工具类,Files包含了大量静态的工具方法来操作文件;Paths则包含了两个返回Path的静态 工厂方法。
Paths 类提供的静态 get() 方法用来获取 Path 对象:
- static Path get(String first, String … more) : 用于将多个字符串串连成路径
- static Path get(URI uri): 返回指定uri对应的Path路径
2.Files类
java.nio.file.Files 用于操作文件或目录的工具类。
三、核心组件:Buffer缓存器
在java IO中体系中, 因为InputStream和OutputStream是抽象类,而java又不可以多重继承,于是任何一个流要么只读,要么只写.而无法完成同时读写的工作,于是: Buffer来了。NIO中,对数据的读写,都是在Buffer中完成的,也就是说,同一个buffer我们可以先读后写, 它底层维护着一个数组,这个数组被三个重要的属性控制,有机的工作结合,使buffer可读可写;
此外,Buffer是线程不安全的,并发访问需要同步
三个重要属性:
- capacity: 容量
Buffer中元素的个数
永远不能为负数
永远不会变化 - limit: 限制
实际上它是Buffer所维护的那个数组中的一个下标
limit是第一个不能被读,或者第一个不能被写的元素的index
limit永远不会是负数
永远不会超过capacity - Position: 定位
指数组中下一个将要被读或者将要被写的元素的索引
CharBuffer
DoubleBuffer
IntBuffer
LongBuffer
ByteBuffer
ShortBuffer
FloatBuffer
以上 Buffer 分别用于对各种基本数据类型进行支持;
四、核心组件:Channel通道
FileChannel:用于文件 I/O
SocketChannel ,ServerChannel:用于 TCP I/O
DatagramChannel:用于 UDP I/O
五、核心组件:Selector选择器、Pipe管道
NIO 的选择器用于监视多个通道的状态(如数据到达,连接打开等),通过选择器,单线程可以监视多个通道中的数据;