对于JavaNIO还是不是很了解,之前认为NIO的N是non-block IO的意思,非阻塞;但是原来是New IO的意思。这个新表示的是和原来的BIO而言是一种新的IO吧。NIO的主要特性就是缓冲区,通道,和选择器(这个可能不是)。
Java在JDK1.4版本呢,引入了NIO这个新的api。Sun公司官方说明NIO的特性如下:
1. 为所有的原始类型提供了(Buffer)缓存支持;
2. 字符集编码解码解决方案
3. Channel(通道):一个新的原始I/O抽象;
4. 支持锁和内存映射文件的文件访问接口;
5. 提供多路(non-blocking)非阻塞式的高伸缩网络I/O。
对于上面的特性,我是不大了解的。不过,不影响,我们继续介绍。
NIO创建的目的是,实现高速的I/O,而无需编写自定义的本机代码。
那NIO大概是怎么做到的呢?它将最耗时的I/O操作转回操作系统,因而可以极大的提高速度。而最耗时的I/O操作是填充和提取缓冲区。
原来的io和现在NIO最重要的区别就是,数据打包和传输的方式。以前是以流,现在是以块的方式处理数据。
之前用流的方式呢,只能一次一个字节的处理数据。一个输入流产生一个字节的数据,而一个输出流则消耗一个字节的数据。这样的好处是,创建过滤器特别容易,可以创建多个过滤器,每个过滤器处理只处理一部分的数据。坏处就是,比较慢。
而NIO用块的方式呢,可以一次一个块的处理数据。每一步的操作都在产生或者消耗一个块,好处是相对于流快得多,坏处是,不够优雅和简单。
然后开始介绍缓冲区,缓冲区就是上面介绍到的NIO的特性第一条,为所有的原始数据都提供了Buffer缓存的支持。它主要是将所有的原始数据放在数组中,以块的形式处理。
而每种缓冲区的类都有四个属性:容量(Capacity),上界(Limit),位置(Position),以及标记(Mark),用于提供关于其所包含的数据元素的信息。
容量:缓冲区能够容纳的数据元素的最大数量,缓冲区创建时确定,永远不能被改变;
上界:缓冲区第一个不能被读或写的元素,或者说,缓冲区现存元素的计数。
位置:下一个要被读或写的元素的索引。该值会自动由相应的get(),put()函数更新;
标记:一个备忘的位置。调用mark()来设定mark=position。调用reset()来设定position = mark;标记在设定前是未定义的undefined。
缓冲区的分类有,ByteBuffer(字节缓冲区),CharBuffer(字符缓冲区),ShortBuffer(短整型缓冲区),IntBuffer(整型缓冲区),LongBuffer(长整型缓冲区),FloatBuffer(单精度浮点缓冲区),DoubleBuffer(双精度浮点缓冲区),就是没有布尔缓冲区。
他们都是抽象类,所以不能实例化,然后他们都继承了Buffer类,所以都有存get(),取set()方法,也都可以通过各自的静态方法allocation,创建缓冲区。该方法是通过warpping将现有的数组包装到缓冲区中来为缓冲区的内容分配空间,或者通过创建现有字节缓冲区的视图来创建。
下面这是一个简单的实例,从上到下,创建一个整型的缓冲区,然后将现有的数组放到该缓冲区中。可以通过put改变数组中的数据,并且由于缓冲区中的数据对数组是可见的,所以改变缓冲区也会改变数据,可以认为是传引用。flip(),由于get()每调用一次,position位置都会改变,本来pos会等于3的,而用flip可以让pos变为0;clear()效果也一样。而duplicate()可以复制一个缓冲区,一模一样,也是传引用,修改哪个都会影响到另一个。
import java.nio.IntBuffer;
import java.util.Arrays;
/**
* Created by liuyanling on 2017/6/30.
*/
public class BufferTest {
public static void main(String[] args) {
//创建缓冲区,并指定大小
IntBuffer intBuffer = IntBuffer.allocate(10);
//给缓冲区赋值,建立数组
int[] intArray = new int[]{3,5,7};
intBuffer = intBuffer.wrap(intArray);
//修改元素
intBuffer.put(0,9);
//打印缓冲区数据
for(int i=0;i System.out.print(temp+"\t"));
//intBuffer.flip();//get()会使pos改变,对缓冲区进行反转,将limit=pos;pos=0; (将当前位置给limit,然后变为0)
intBuffer.clear();
System.out.println(intBuffer);
IntBuffer intBuffer2 = intBuffer.duplicate();
System.out.println(intBuffer2);
intBuffer2.put(0,11);
//0 <= mark <= position <= limit <= capacity
//打印缓冲区数据
for(int i=0;i
结果是这样
9 5 7
缓冲区的数据对数组是可见的,修改视图,数组中的数据也会变;传引用
9 5 7 java.nio.HeapIntBuffer[pos=0 lim=3 cap=3]
java.nio.HeapIntBuffer[pos=0 lim=3 cap=3]
11 5 7
复制的缓冲区对原来的缓冲区也是可见的;传引用
11 5 7
未完待续!