您的位置:首页 > 编程语言 > Java开发

Java Non-blocking I/O(NIO);NIO2及Asynchronous I/O基础

2018-03-08 00:00 239 查看
Java Non-blocking I/O(NIO)介绍
项目地址:https://github.com/bfylu/java-io
在Classic I/O库中,数据直接面向Stream写入或者读取,而在NIO库中,数据读取与写入面向的是Buffer对象,
这种差异使性能得到了巨大提高.
缓冲区实质上眄一个数组,java.nio库中提供了Buffer抽象类,基于该抽象类,实现了一系列Java基本类型的
Buffer子类,Buffer类图:

Buffer
|
/|\
____________________________________|_________________________________
|           |            |          |         |          |           |
|           |            |          |         |          |           |
ByteBuffer      |        DoubleBuffer   |      IntBuffer     |       ShortBuffer
/|\       CharBuffer            FloatBuffer           LongBuffer
|
MappedByteBuffer

所有的缓冲区都具有以四个属性来提供关于其所包含的数据元素的信息.
*       容量(Capacity):缓冲区能够容纳的数据元素的最大数量.这一容量在缓冲区创建时被设定,并且永远不能被
修改.

*       上界(Limit):缓冲区的第一个不能被读或写的元素.或者说,缓冲区中现存元素的计数.

*       位置(Position):下一个要被读或写的元素的索引.位置会自动由相应的get()和put()函数更新

*       标记(Mark):一个备忘位置.调用mark()来设定mark=postion.调用reset()设定position=mark.标记
在设定前是未定义的(undefinde).

这四个属性之间总是遵循以下关系:
0<=mark <=position <=limit <=capacity

Buffer主要的API:
*       public final int capacity():返回capacity

*       public final int position()返回position

*       public final Buffer position(int newPosition): 设置新的position

*       public final int limit(): 返回 新的limit

*       public final Buffer mark():将当前的position值设置为mark

*       public final Buffer reset():将position 的值设置为前一次设置的mark 值

*       public final Buffer clear():清空Buffer,将position 值设置为0,limit 设置为capacity,
mark 值设置为无效

*       public final Buffer flip():翻转Buffer,为读Buffer 做准备。limit 设置为当前的position,
position值为0,mark值为无效。

*       public final Buffer rewind():倒回Buffer,为重新读取Buffer做准备。Position值为0,mark
值为无效。

*       public final int remaining():返回Buffer中数据个数,即当前position与limit之间的数据

*       public final boolean hasRemaining():判断Buffer是否有数据。

Classic I/O中的Stream是单向的,通过OutputStream实现输出流,InputStream实现输入流.而NIO中的Channel
是一个全双工通道,可以通过Channel实现同时读取与写入.

通道据的具体实现分为文件读写通道与网络读写通道.最重要的通道实现如下:

*       FileChannel:从文件中读写数据.

*       DatagramChannel:通过UDP协议读写网络数据

*       SocketChannel:通过TCP/IP协议读写网络数据,客户端连接通道

*       ServerSocketChannel:SocketChannel对应的服务端通道实现,通过监听新的TCP/IP连接,对每一个新
的连接创建的SocketChannel.

Selector选择器
Channel在Selector上注册,Selector通过不断轮询注册在其上的Channel,能够感知到Channel可读或者可写
事件.通过这种机制,可以使用一个或者少数几个线程管理大量的网络连接.

Socket          Socket          Socket          Socket
/|\             /|\             /|\             /|\
|               |               |               |
SocketChannel  SocketChannel  SocketChannel    SocketChannel
|               |               |               |
|               |               |               |
_\|/_____________\|/_____________\|/_____________\|/_
|
\|/
Selector
/|\
|
Thread

NIO2及Asynchronous I/O介绍
JDK7对原有的NIO进行了大幅度的升级,我们称为NIO2.NIO2主要改进了Classic I/O中java.io.File类对文件
操作的局限性,比如,新引入了Path及Paths,Files,Directories等工具类,支持符号链接,扩展了文件的属性支持
类型,新的API支持文件的复制与移动等.此外,NIO2还带来了真正意义上的Asynchronous I/O(异步I/O),具体实现
分为文件Asynchronous I/O与网络传输AsynchronousI/O.

1. Path介绍:Path抽象了文件路径,可看作java.is.File类的升级版.Path是NIO2中的基础类之一,
NIO2中大量的I/O操作都会用到该类.

2. Paths,Files工具类介绍
NIO2在易用性方面很大的一个提升源于提供了一些很好用的工具类,比如Paths和Files.

Paths工具类如下:
*       public static Path get(String first, String... more):将多个路径段组合成一个新的Path

*       public static Path get(URI uri):根据uri创建Path.

通过以上两个静态方法,能够很方便地构造Path对象.
File工具类常用方法如下:
*       public static InputStream newInputStream(Path path, OpenOption... options):获得文件输入流

*       public static OutputStream newOutputStream(Path path,OpenOption... options):获得文件输出流.

*       public static SeekableByteChannel newByteChannel(Path path,Set<? extends OpenOption> options,FileAttribute<?>... attrs):获得文件通道.

*       public static DirectoryStream<Path> newDirectoryStream(Path dir):能够通过返回对象
DirectoryStream获取迭代器Iterator.进而获取到参数目录dir下的一级目录或者文件.

*       public static Path CreateFile(Path path,FileAttribute<?>... attrs):创建文件,并返回所创建文件的Path对象

*       public static Path CreateDirectory(Path dir, FileAttribute<?>... attrs):创建目录,并返回创建目录的Path对象

*       public static Path createDirectories(Path dir, FileAttriBute<?>... attrs):递归创建目录,并返回所创建目录的Path对象

*       public static Path createTempFile(Path dir,String prefix,String suffix,FileAttribute<?>... attrs):创建临时文件

*       public static Path createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs):创建指定Path的符号链接

*       public static void delete(Path path):删除Path所代表的文件

*       public static boolean deleteIfExists(Path path): 如果Path所代表的文件存在,删除Path所代表的文件

*       public static Path copy(Path source,Path target,CopyOption... options):文件复制

*       public static Path move(Path source,Path target,CopyOption... options):移动文件

*       public static Path readSymbolicLink(Path link):读取符号链接文件

*       public static boolean isSameFile(Path path, Path path2):判断是否是同一个文件

*       public static boolean isReadable(Path path):判断文件是否可读

*       public static boolean isWritable(Path path):判断文件是否可写

*       public static boolean isExecutable(Path path):判断文件是否可执行.

*       public static BufferedReader newBufferedReader(Path path, Charset cs):获取文件的缓冲字节输入流

*       public static BufferedWriter newBufferedWriter(Path path, Charset cs, OpenOption... options):获取文件的缓冲字节输出流

*       public static long copy(InputStream in,Path target, CopyOption... options):从文件输入流获取文件内容实现文件复制

*       public static long copy(Path source, OutputStream out):将文件复制到文件输出流

*       public static byte[] readAllBytes(Path path):读取文件,返回文件内容字节数组

*       public static List<String> readAllLines(Path path, Charest cs):读取文件,返回文件内容字符串数组

*       public static Path write(Path path,byte[] bytes, OpenOption... option):将字节数组内容写入指定的文件

*       public static Path write(Path path,Iterable<? extends CharSequesce> lines,Charest cs,OpenOption... options):将字符串数组写入指定的文件.

WatchService接口
java.nio.file.WatchService接口的引入是NIO2对于文件操作功能的一个很大的提升,它提供了通过应用程序患得监听操作系统文件变更
事件的能力.通过在Path上注册所需要患得监听的事件(文件创建,文件修改,文件删除),一旦被监听的文件发生变更,应用程序能够实时感知到
这种变化

文件读写Asynchronous I/O
NIO2通过AsynchronousFileChannel提供了异步读取文件的功能.通过AsynchronousFileChannel异步读写文件有
CompletionHandler与Future两种方式.

Java异步I/O网络通信实现
NIO2通过引入AsynchronousSocketChannel与AsynchronousServerSocketChannel实现了异步I/O网络通信模型.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA NIO NIO2