1.   基本 概念

 


     IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。

  所有语言运行时系统提供执行 I/O 较高级别的工具。 (c 的 printf scanf,java 的面向对象封装 )  



2.    Java 标准 io 回顾

 


      Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底层实现,我们无须关注底层实现。 InputStream\OutputStream( 字节流 ) :一次传送一个字节。 Reader\Writer( 字符流 ) :一次一个字符。

 



3.    nio 简介

 


      nio

  是   java New IO   的简称,在   jdk1.4   里提供的新   api   。   Sun   官方标榜的特性如下:  


–     为所有的原始类型提供 (Buffer) 缓存支持。

 


–     字符集编码解码解决方案。

 


–     Channel :一个新的原始 I/O 抽象。

 


–     支持锁和内存映射文件的文件访问接口。

 


–     提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I/O 。

 


本文将围绕这几个特性进行学习和介绍。

 



4.   Buffer&Chanel

 


     Channel

  和   buffer   是   NIO   是两个最基本的数据类型抽象。  


     Buffer:

 


–        是一块连续的内存块。

 


–       是 NIO 数据读或写的中转地。

 


Channel:

 


–       数据的源头或者数据的目的地

 


–       用于向 buffer 提供数据或者读取 buffer 数据 ,buffer 对象的唯一接口。

 


–      异步 I/O 支持 


         java原来的I/O体系中, I/O实际上是以Stream(流)这个抽象概念被使用,所有的I/O实际上被看做是单个字节一个字节一个字节的移动; Stream I/O被用来和外界世界交互,在内部它用来将对象转为bytes字节流,然后再转为对象;

         NIO的角色和目标实际上和原来的I/O是相同的,但是它使用了一个不同的抽象概念:block I/O. 正如你将所见到的那样,block I/O比原来的I/O有效率得多;

Streams和blocks的对比     

         原来的I/O包和NIO处理数据最大的不同之处在于数据打包(packaged)和传输(transmitted)的方式。正如前面所提到的那样,IO(java.io.*)是以流的方式处理数据的,而NIO是以blocks(块)的方式来处理数据的.

         一个流面向(stream-oriented)的I/O系统在处理数据时是一次只处理一个字节;作为input的stream一次向计算机生产一个byte,作为output的stream一次向计算机要求消费一个byte(计算机生产byte),对stream创建filter是一件非常容易的事情,同时如果你希望通过chain模式将几个filter连在一起也很容易,最终可以将大量复杂的处理分成一个简单,巧妙的处理模式;但是同时,stream-oriented的I/O处理通常非常低效率。

         而一个块面向(block-oriented)的I/O系统成块的处理数据,每次操作都会生产或者消费以block为单位的数据;所以,这种方式会比stream-oriented的处理方式高效地多,但是block-oriented的I/O也缺少以stream-oriented编程时的简单和优雅;




什么是buffer?:

         当数据写入或者数据读取时,这些数据被保存在一个buffer对象中;buffer对象是nio和原io包中一个最重要的区别。在原来的io系统中,数据的读取和获得是首先通过Stream流对象。

         在nio中,所有的数据采用buffers的方式进行处理。当数据被读取的时候,读入数据被先保存到buffer中;数据写入的时候,写入数据也首先放置到buffer中。

         一个buffer对象实际上是一个array对象,但是又不单单只具有array的功能;一个buffer对象提供了结构化访问数据的能力,并且记录了系统读/写操作的日志。

buffer的类型?:

         最常见的使用buffer的方式是ByteBuffer,一个ByteBuffer的底层数组允许get/set  buffers的操作;

         其他的buffer类型包括:CharBuffer,ShotBuffer,

 IntBuffer, LongBuffer, DoubleBuffer,FloatBuffer;

         每一种buffer的类型都是一个buffer接口;这些接口的行为除了处理的数据不同之外, 操作行为非常相似; 不过因为ByteBuffer被用来和大多数标准的I/O操作,所以除了共有的buffer操作之外,还有一些特别的操作行为;

什么是channel?:

         一个Channel是一个可以操作读写数据的对象,channel的概念类似于io包中的stream(流)概念;

         如前所述,在nio中,所有的数据是通过buffer这个对象进行处理的;在读写数据的时候,你永远不需要直接地操作Channel对象;

channel的类型?:

         和io中流(Stream)概念不同的是,channel是双向的;一个流必须是InputStream或者OutputStream的子类,一个Channel可以是读/写操作的任何一种或两种;因为channel的双向特性,和流比起来更真实地反映了os的底层,尤其在Unix中。