java中的NIO

使用传统的输入输出流,当读取输入流中的数据如果没有没有读到有效的数据时,程序将在此处阻塞该线程的执行(使用InputStream的read方法从流中读取数据时,如果数据源中没有数据,它也会阻塞该线程),传统的输入、输出流都是阻塞式的输入输出。不仅如此,传统的输入、输出流都是通过字节的移动来处理的(即使我们可以不直接去处理字节流,但底层的实现还是依赖于字节处理流),也就是说面向流的输入、输出系统一次只能处理一个字节,因此面向流的输入、输出系统通常效率不高。

    从jdk1.4开始,java提供了一系列改进的输入、输出处理的新特性。新IO和传统的IO有相同目的,都是用于进行输入、输出的功能。

新IO使用了不同的方式来处理输入、输出,新IO采用内存映射文件的方式来处理输入输出,新IO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了,通过这种方式来进行输入、输出比传统的输入输出要快的多。

新IO中的两个核心的对象是:Buffer(缓冲)和Channel(通道)。Channel与传统的InputStream、OutputStream最大的区别在于它提供了一个map方法,通过该map方法可以直接将“一块数据”映射到内存中去。如果说传统的流处理方式是面向流的,那么新IO则是面向块的处理。Buffer可以被理解成一个容器,它的本质是一个数组,发送到Channel中的所有对象都必须放到Buffer中,而从Channel中读取的数据也必须先读到Buffer中。

一、Buffer

    Buffer是一个抽象类,从内部结构来看,Buffer就像一个数组,它可以在底层字节数组上进行set/get操作。对应其他基本数据类型(boolean除外)都有相应的Buffer类:ByteBuffer、CharBuffer、ShortBuffer、等。

   创建Buffer对象:static   XXXBuffer allocate(int capacity)

   在Buffer中有三个重要的概念:容量(capacity)、界限(limit)、和位置(position)(位置是从0开始的)。

  当Buffer装入数据结束后,调用Buffer的flip方法,该方法将limit设置为position所在位置,将position设置为0,这样使得从Buffer中读取数据时总是从0开始。

  当Buffer输出数据结束后,Buffer调用clear方法,clear方法是将position设置为0,limit设置为capacity,这样为再次向Buffer中写入数据做好准备。

二、Channel

    Channel类似于传统的流对象,但与传统的流不同的是,Channel有两个主要的区别:

     ①、Channel可以直接将指定文件的部分或全部直接映射成Buffer。

    ②、程序不能直接访问Channel中的数据,包括读取、写入都不行,Channel只能与Buffer进行交互。

     Channel也是一个接口,系统为该接口提供了DatagramChannel、FileChannel等实现类。

    所有的Channel都不应该通过构造器来创建,而是通过传统的节点InputStream、OutputStream的getChannel方法来创建。在RandomAccessFile中也包含一个getChannel方法。

   Channel中最常用的三个方法:map、read、write,其中map方法用于将Channel对应的部分或全部数据映射的ByteBuffer。

posted on 2014-02-22 20:29  那些年我们一起奋斗的日子  阅读(249)  评论(0编辑  收藏  举报