前言:
Jdk自1.4版本开始,提供给我们一种新的IO操作,即NIO(new io),这种新的io不同与之前的io操作(java.io包
下),感觉是个废话。我们称java.io包下的io为BIO(blocking io)。Jdk1.7版本开始,又给我们提供了第三招IO操
作,即AIO(asynchronous io),之所以有不同这么io,原因取决于底层(操作系统)的区别,具体的区别参阅”系
统的几种IO模型”。这篇文章介绍我对nio的掌握理解。
Nio包总体结构了解:
Java.nio包
Java.nio.channel包
我们知道java程序跑在jvm上,sun公司向下屏蔽了底层的具体操作,向上为我们提供了抽象的形象的api,
方便我们使用,nio抽象的还原了底层进行io操作的情况,又使我们开发人员便于理解学习。
理解nio:
我们知道,跑在操作系统上的程序,当程序发生与硬件相关的操作时,并非我们的程序直接与硬件交
互,都是程序调用操作系统函数,操作系统再去与具体的硬件交互的。这也是IO的操作基本流程。Java
程序也不例外,现在就来看看javanio是如何进行操作的:
Nio是基于通道+缓冲器来抽象应用程序io操作的
通道(Channel):很好理解。道路,走廊等等,都可认为是通道,即起始点间打通,能够传输的。
计算机中可认为是程序(内存)到操作系统,再到外部介质(磁盘,网络等)的能够传
输数据的通道,理解起来是不是不难,光有通道也不行,得有东西在上面传递。
缓冲器(Buffer):这就是数据的存储器,我们知道真正的IO操作不是程序本身去做,而是由操作
系统去实现,程序只是把数据准备好,然后向操作发送读或写信号,系统就将
程序准备的数据进行读写,而程序准备的数据就放在缓冲器中。
Nio主要就是这两个核心概念。下面再具体看看nio的api。.
API介绍:
通过上面的关系图,可以看出来,根据终点的不同,可以分成大致如下几种通道:
DatagramChannel:数据报套接字通道(UDP网络)
ServerSocketChannel:侦听套接字通道
SocketChannel:连接套接字通道
Pipe.SinkChannel:管道传送的通道(可写入)
Pipe.SourceChannel:管道传送的通道(可读取)
FileChannel:文件通道
方法介绍:读写方法每个通道都有,同时需要将缓冲器最为参数放进去(注意,仅仅是一个系统调用,
具体由系统去做;其次不同于bio的是,通道是双向的,可读可写),方法请参看这里。
接下来,看看缓冲器,通过上图看出可分为:
ByteBuffer:字节缓存器
CharBuffer :字符缓冲
DoubleBuffer :double 缓冲区器
FloatBuffer :float 缓冲区
IntBuffer :int缓冲器
LongBuffer :long缓冲器
MappedByteBuffer :直接字节缓冲区(内容是文件的内存映射区域)
ShortBuffer:short缓冲器
ByteOrder:字节序的类型安全枚举(即大小端)
通过上面介绍基本对nio有了较全面的了解了,先脉络后细节,我们先要有个宏观上的把握,这样学习
具体的才能便于理解和记忆。这里还有个小的知识点(也就是java.nio.charset 包),没介绍,接下来就看
看java.nio.charset包。
java.nio.charset包:
根据包名也就知道是干什么的了,字符集的问题。这个其实可以类比bio,在bio中,当在非字节流的操作
情况下,我们都需要指定一个字符集来读,写流,这样才能保证不会出现乱码的现象。java.nio.charset
包也就是nio中进行读,写到通道时指定的字符集。
主要有3个类:
Charset :提供解码,编码;Unicode 代码单元序列和字节序列之间的指定映射关系的类。
CharsetDecoder :解码器,用于将字节序列转换成 16 位 Unicode 字符序列。
CharsetEncoder :编码器,用于将Unicode 字符序列转成 charset 中字节序列。
在nio中放进通道的缓冲器只能为ByteBuffer(字节缓冲器),所以程序中使用了字符等其他的缓冲器时,
当进行读写,要先转成字节缓冲器。
下一篇文章会根据一个简单代码了解如何使用nio的相关api。