NIO学习系列笔记(1)
2015-11-12 17:40
302 查看
在JDK1.4以前,I/O输入输出处理,我们把它称为旧I/O处理,在JDK1.4开始,java提供了一系列改进的输入/输出新特性,这些功能被称为新I/O(NEW I/O),新添了许多用于处理输入/输出的类,这些类都被放在java.nio包及子包下,并且对原java.io包中的很多类以NIO为基础进行了改写,新添了满足新I/O的功能。
旧I/O中,java.io包中的类,如BufferedReader读取输入流中的数据时,如果没有读到有效数据时,程序将在此处阻塞该线程的执行(InputStream中的read方法也是如此),简单一点说,旧的i/o流,是属于阻塞式输入,输出.而且传统的输入,输出都是通过字节的移动来处理,也就是说面向流的输入/输出系统一次只能处理一个字节,因此面向流的输入/输出系统通常效率不高.所以就出现了新I/O了。
新IO和传统的IO有相同的目的,都是用于进行输入/输出功能,但新IO使用了不同的方式来处理输入输出,新IO采用内存映射文件的方式来处理输入输出,新IO将文件或文件的一段区域映射到内存中,这样就可以象访问内存一样来访问文件了,通过这种方式来进行输入输出比传统的输入输出要快得多.
JAVA中NIO相关的包如下
java.nio 包:主要提供了一些和Buffer相关的类
java.nio.channels包:主要包括Channel和Selector相关的类
java.nio.charset包:主要包含和字符集相关的类
java.nio.channels.spi包:主要包含提供Channel服务的类
java.nio.charset.spi包:主要包含提供字符集服务的相关的类
Channel(通道)和Buffer(缓冲)是新io中的两个核心对象
Channel是对传统输入输出系统中的模拟,在新io系统中所有数据都需要通过通道传输;Channel与传统瓣InputStream、OutputStream最大的区别在于它提供了一个map方法,通过该map方法可以直接将“一块数据”映射到内存中。如果说传统的输入输出系统是面向流的处理,而新io则是面向块的处理.
Buffer可以理解成一个容器,它的本质是一个数组,发送到Channel中的所有对象都必须首先放到Buffer中,而从Channel中读取的数据也必须先读到Buffer中.此处的Buffer有点类似于“竹筒”,该Buffer既可以象前面那样一次,一次去Channel中取水,也允许使用Channel直接将文件的某块数据映射成Buffer
(一)使用Buffer
从内部结构上来看,Buffer就象一个数组,它可以保存多个类型相现的数据。Buffer是一个抽象类,其最常用的子类是ByteBuffer,它可以在底层字节数组上进行 get/put操作,除了 ByteBuffer之外,对应其它数据类型(boolean除外),都有相应的Buffer类:ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer.
上面这些Buffer类,除了ByteBuffer之外,它们都采用相同或相似的方法来管理数据,只是管理的数据类型不同而也。这些Buffer都没有提供构造器,通过使用如下方法来得到一个Buffer对象.
static XxxBuffer allocate(int capacity):创建一个容量为capacity的XxxBuffer对象
实际使用较多的是ByteBuffer和CharBuffer,其它Buffer子类则较少用到.
在Buffer有三个重要的概念:容量(Capacity),界限(limit),和位置(position)
容量(Capacity):缓冲区的容量表示 该Buffer的最大数据容量,即最多可以存储多少数据。
界限(limit):第一个不应该被读出或者写入的缓冲区位置索引.也就是说,位于limit后的数据既不可读,也不可写
位置(position):用于指明下一个可以被读出的或者写入的缓冲区位置索引(类似于io流的记录指针)
下图是某个Buffer读入了一些数据后的示意图
Buffer有两个非常重要的方法:flip和Clear方法
(1)当Buffer装入数据结束后,调用Buffer的flip方法,该方法将limit设置为position所在位置,将position设为0,这样使得从Buffer中读数据时总是从0开始,读完刚刚装入的所有数据即结束,也说是Buffer调用flip方法后,Buffer为输出数据做好了准备.
(2)当Buffer调用clear方法,clear方法不是清空Bufferr的数据,它仅仅将postion 的位置置为0,将limit置为 capacity,这样为再次向Buffer中装入数据做好了准备.
(3)flip为从Buffer中取出数据做好准备,clear则向Buffer中装入数据做好准备.
下面程序示范了Buffer的一些常规操作
(下面有运行结果,如有疑问,可以留言)
import java.nio.*;
public class BufferTest
{
public static void main(String[] args)
{
//创建Buffer
CharBuffer buff = CharBuffer.allocate(8); //1
System.out.println("capacity: "
+ buff.capacity());
System.out.println("limit: "
+ buff.limit());
System.out.println("position: "
+ buff.position());
//放入元素
buff.put('a'); //2
buff.put('b'); //3
buff.put('c'); //4
System.out.println("加入三个元素后,position = "
+ buff.position());
//调用flip()方法
buff.flip(); //5
System.out.println("执行flip()后,limit = "
+ buff.limit());
System.out.println("position = "
+ buff.position());
//取出第一个元素
System.out.println("第一个元素(position=0):"
+ buff.get()); //6
System.out.println("取出一个元素后,position = "
+ buff.position());
//调用clear方法
buff.clear(); //7
System.out.println("执行clear()后,limit = "
+ buff.limit());
System.out.println("执行clear()后,position = "
+ buff.position());
System.out.println("执行clear()后,缓冲区内容并没有被清除:"
+ buff.get(2)); //8
System.out.println("执行绝对读取后,position = "
+ buff.position());
}
}
运行结果
旧I/O中,java.io包中的类,如BufferedReader读取输入流中的数据时,如果没有读到有效数据时,程序将在此处阻塞该线程的执行(InputStream中的read方法也是如此),简单一点说,旧的i/o流,是属于阻塞式输入,输出.而且传统的输入,输出都是通过字节的移动来处理,也就是说面向流的输入/输出系统一次只能处理一个字节,因此面向流的输入/输出系统通常效率不高.所以就出现了新I/O了。
新IO和传统的IO有相同的目的,都是用于进行输入/输出功能,但新IO使用了不同的方式来处理输入输出,新IO采用内存映射文件的方式来处理输入输出,新IO将文件或文件的一段区域映射到内存中,这样就可以象访问内存一样来访问文件了,通过这种方式来进行输入输出比传统的输入输出要快得多.
JAVA中NIO相关的包如下
java.nio 包:主要提供了一些和Buffer相关的类
java.nio.channels包:主要包括Channel和Selector相关的类
java.nio.charset包:主要包含和字符集相关的类
java.nio.channels.spi包:主要包含提供Channel服务的类
java.nio.charset.spi包:主要包含提供字符集服务的相关的类
Channel(通道)和Buffer(缓冲)是新io中的两个核心对象
Channel是对传统输入输出系统中的模拟,在新io系统中所有数据都需要通过通道传输;Channel与传统瓣InputStream、OutputStream最大的区别在于它提供了一个map方法,通过该map方法可以直接将“一块数据”映射到内存中。如果说传统的输入输出系统是面向流的处理,而新io则是面向块的处理.
Buffer可以理解成一个容器,它的本质是一个数组,发送到Channel中的所有对象都必须首先放到Buffer中,而从Channel中读取的数据也必须先读到Buffer中.此处的Buffer有点类似于“竹筒”,该Buffer既可以象前面那样一次,一次去Channel中取水,也允许使用Channel直接将文件的某块数据映射成Buffer
(一)使用Buffer
从内部结构上来看,Buffer就象一个数组,它可以保存多个类型相现的数据。Buffer是一个抽象类,其最常用的子类是ByteBuffer,它可以在底层字节数组上进行 get/put操作,除了 ByteBuffer之外,对应其它数据类型(boolean除外),都有相应的Buffer类:ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer.
上面这些Buffer类,除了ByteBuffer之外,它们都采用相同或相似的方法来管理数据,只是管理的数据类型不同而也。这些Buffer都没有提供构造器,通过使用如下方法来得到一个Buffer对象.
static XxxBuffer allocate(int capacity):创建一个容量为capacity的XxxBuffer对象
实际使用较多的是ByteBuffer和CharBuffer,其它Buffer子类则较少用到.
在Buffer有三个重要的概念:容量(Capacity),界限(limit),和位置(position)
容量(Capacity):缓冲区的容量表示 该Buffer的最大数据容量,即最多可以存储多少数据。
界限(limit):第一个不应该被读出或者写入的缓冲区位置索引.也就是说,位于limit后的数据既不可读,也不可写
位置(position):用于指明下一个可以被读出的或者写入的缓冲区位置索引(类似于io流的记录指针)
下图是某个Buffer读入了一些数据后的示意图
Buffer有两个非常重要的方法:flip和Clear方法
(1)当Buffer装入数据结束后,调用Buffer的flip方法,该方法将limit设置为position所在位置,将position设为0,这样使得从Buffer中读数据时总是从0开始,读完刚刚装入的所有数据即结束,也说是Buffer调用flip方法后,Buffer为输出数据做好了准备.
(2)当Buffer调用clear方法,clear方法不是清空Bufferr的数据,它仅仅将postion 的位置置为0,将limit置为 capacity,这样为再次向Buffer中装入数据做好了准备.
(3)flip为从Buffer中取出数据做好准备,clear则向Buffer中装入数据做好准备.
下面程序示范了Buffer的一些常规操作
(下面有运行结果,如有疑问,可以留言)
import java.nio.*;
public class BufferTest
{
public static void main(String[] args)
{
//创建Buffer
CharBuffer buff = CharBuffer.allocate(8); //1
System.out.println("capacity: "
+ buff.capacity());
System.out.println("limit: "
+ buff.limit());
System.out.println("position: "
+ buff.position());
//放入元素
buff.put('a'); //2
buff.put('b'); //3
buff.put('c'); //4
System.out.println("加入三个元素后,position = "
+ buff.position());
//调用flip()方法
buff.flip(); //5
System.out.println("执行flip()后,limit = "
+ buff.limit());
System.out.println("position = "
+ buff.position());
//取出第一个元素
System.out.println("第一个元素(position=0):"
+ buff.get()); //6
System.out.println("取出一个元素后,position = "
+ buff.position());
//调用clear方法
buff.clear(); //7
System.out.println("执行clear()后,limit = "
+ buff.limit());
System.out.println("执行clear()后,position = "
+ buff.position());
System.out.println("执行clear()后,缓冲区内容并没有被清除:"
+ buff.get(2)); //8
System.out.println("执行绝对读取后,position = "
+ buff.position());
}
}
运行结果
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- spymemcached源码中Reactor模式分析
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树