最近学习Java NIO的相关知识,为了以后方便复习,记录下主要知识点。
参考来源:某视频中的讲解以及一些博文,见文章结尾。
一、Java NIO基本介绍
Java NIO(New IO,也有人叫:Non Blocking IO)是从Java1.4版本开始引入的一个新的IO API,其与原来的IO有同样的作用和目的,但是使用方式有很大的差别。NIO是为提供I/O吞吐量而专门设计,其卓越的性能甚至可以与C媲美。NIO是通过Reactor模式的事件驱动机制来达到Non blocking的,那么什么是Reactor模式呢?Reactor翻译成中文是“反应器”,就是我们将事件注册到Reactor中,当有相应的事件发生时,Reactor便会告知我们有哪些事件发生了,我们再根据具体的事件去做相应的处理(引用自:NIO介绍)。
NIO支持面向缓冲区的、基于通道的IO操作,将以更加高效的方式进行文件的读写操作。
NIO的三个核心模块:Buffer(缓冲区)、Channel(通道)、Selector(选择器)。
二、Java NIO与IO的主要区别
IO | NIO |
---|---|
面向流(Stream Oriented) | 面向缓冲区(Buffer Oriented) |
阻塞IO(Blocking IO) | 非阻塞IO(Non Blocking IO) |
无 | 选择器(Selectors) |
三、通道和缓冲区
1.缓冲区:
1.1 基本概念:缓冲区(Buffer)就是在内存中预留指定字节数的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区;
1.2 作用:用来临时存储数据,可以理解为是I/O操作中数据的中转站。缓冲区直接为通道(Channel)服务,写入数据到通道或从通道读取数据,这样的操利用缓冲区数据来传递就可以达到对数据高效处理的目的。
1.3 类型:Buffer就像一个数组,可以保存多个相同类型的数据,根据数据类型的不同(Boolean类型除外),有以下七个Buffer常用的子类:ByteBuffer、CharBuffer 、ShortBuffer 、IntBuffer 、LongBuffer 、FloatBuffer 、DoubleBuffer 。
1.4 缓冲区的四个基本属性
属性 | 概念 |
---|---|
容量(capacity) | 表示Buffer最大的数据容量,缓冲区的容量不能为负数,而且一旦创建,不可修改 |
限制(limit) | 缓冲区中当前的数据量,即位于limit之后的数据不可读写 |
位置(position) | 下一个要读取或写入的数据的索引 |
标记(mark) | 调用mark()方法来记录一个特定的位置:mark=position,然后再调用reset()可以让position恢复到标记的位置即position=mark |
*** 容量、限制、位置、标记遵守以下不变式:0 <= mark <= position <= limit <= capacity
1.5 创建缓冲区:获取一个指定容量的xxxBuffer对象,以ByteBuffer为例:
创建一个容量大小为1024的ByteBuffer数组,需要注意的是:所有的缓冲区类都不能直接使用new关键字实例化,它们都是抽象类,但是它们都有一个用于创建相应实例的静态工厂方法:static XxxBuffer allocate(int capacity);
1.6 缓冲区的两个数据操作方法:put()和get()
get();获取Buffer中的数据put(),放入数据到Buffer中。
1.7 flip()方法:将写数据状态切换为读数据状态
flip()的源码:
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
具体操作代码如下:
// 1.创建一个容量为1024的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
// 2.往缓冲区里写数据
String str = "abcde";
buf.put(str.getBytes());
// 3.切换数据模式
buf.flip();
// 4.读取数据
byte[] dst = new byte[buf.limit()];
buf.get(dst);
1.8 直接缓冲区