Java入门9.2---NIO(Non-Blocking IO,New IO)

一、简介

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 对象:

  1. static Path get(String first, String … more) : 用于将多个字符串串连成路径
  2. static Path get(URI uri): 返回指定uri对应的Path路径
    image

2.Files类

java.nio.file.Files 用于操作文件或目录的工具类。
image
image

三、核心组件:Buffer缓存器

在java IO中体系中, 因为InputStream和OutputStream是抽象类,而java又不可以多重继承,于是任何一个流要么只读,要么只写.而无法完成同时读写的工作,于是: Buffer来了。NIO中,对数据的读写,都是在Buffer中完成的,也就是说,同一个buffer我们可以先读后写, 它底层维护着一个数组,这个数组被三个重要的属性控制,有机的工作结合,使buffer可读可写;
此外,Buffer是线程不安全的,并发访问需要同步
三个重要属性:

  1. capacity: 容量
    Buffer中元素的个数
    永远不能为负数
    永远不会变化
  2. limit: 限制
    实际上它是Buffer所维护的那个数组中的一个下标
    limit是第一个不能被读,或者第一个不能被写的元素的index
    limit永远不会是负数
    永远不会超过capacity
  3. 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 的选择器用于监视多个通道的状态(如数据到达,连接打开等),通过选择器,单线程可以监视多个通道中的数据;
image

参考链接:
【1】JAVA NIO学习一:NIO简介、NIO&IO的主要区别 - pony1223 - 博客园

原文地址:https://www.cnblogs.com/nxf-rabbit75/p/14861045.html