java网络编程 nio
java.nio的包是在jdk1.4以后被提出来的,和原来的i/o开发模式比起来,nio提供了高性能,block-oriented I/O的编程模式; 和原来的I/O包相比,通过定义classes保存数据和blocks方式来处理数据,而不是使用native的代码编程;
Input/Output的概念:
I/O – 或者说Input/Output – 是一种计算机和其他设备之间,或者说是某一程序和计算机的其他设备之间的接口。它是所有计算机系统中如此关键,以至于在I/O的实际上内置在OS中,个人程序的大多数工作是在和它打交道;
java原来的I/O体系中, I/O实际上是以Stream(流)这个抽象概念被使用,所有的I/O实际上被看做是单个字节一个字节一个字节的移动; Stream I/O被用来和外界世界交互,在内部它用来将对象转为bytes字节流,然后再转为对象;
NIO的角色和目标实际上和原来的I/O是相同的,但是它使用了一个不同的抽象概念:block I/O. 正如你将所见到的那样,block I/O比原来的I/O有效率得多;
为什么使用NIO呢?
NIO可以让java程序员在和传统的native编码方式不同的方式下,实现高性能的输入/输出效果,NIO把大多数消耗时间的I/O操作(namely,filling,draining buffer)的行为交给操作系统,所以性能上相比有了很大提升;
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编程时的简单和优雅;
I/O综述:
JDK1.4以后,原来的I/O和NIO已经很好地结合在一起了,java.io.*的体系用nio作为它的基础进行了代码重构,所以java.io.*现在可以使用nio的一些特性.譬如,java.io.*中的一些class包含一些成块读写数据的方法,所以这样的话虽然在java.io中,还是带来了一些更快的执行效率;
你同样可以用nio来实现一些标准的I/O函数,例如,你可以方便的使用block I/O以字节的方式来地移动数据,但是,nio还是提供了很多在io包中所没有的便利方法;
NIO之:Channels和Buffers
简介:
channels和buffer是nio中几乎每次I/O交互中核心的对象。
channels的概念和原IO中的stream的概念类似。数据的读取和获取必须通过一个channel对象;而buffer实际上是一个容器对象,所有通过channel读写的数据最终都是以buffer的形式交互的;
什么是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中。