陆小曼|Java IO,讲的实在是太好了,这篇( 七 )


新潮的NIO我们来看看BIO和NIO的区别 , BIO是面向流的IO , 它建立的通道都是单向的 , 所以输入和输出流的通道不相同 , 必须建立2个通道 , 通道内的都是传输0101001···的字节数据 。
通道(铁路)只是作为运输数据的一个连接资源 , 而真正存储数据的是缓冲区(火车) 。 即通道负责传输 , 缓冲区负责存储 。
BIONIO面向流(Stream)面向缓冲区(Buffer)单向通道双向通道阻塞IO非阻塞IO选择器(Selectors)
缓冲区(Buffer)缓冲区是存储数据的区域 , 在Java中 , 缓冲区就是数组 , 为了可以操作不同数据类型的数据 , Java提供了许多不同类型的缓冲区 , 除了布尔类型以外 , 其它基本数据类型都有对应的缓冲区数组对象 。
在Java中 , boolean类型数据只占用1bit , 而在IO传输过程中 , 都是以字节为单位进行传输的 , 所以boolean的1bit完全可以使用byte类型的某一位 , 或者int类型的某一位来表示 , 没有必要为了这1bit而专门提供多一个缓冲区 。
缓冲区解释ByteBuffer存储字节数据的缓冲区CharBuffer存储字符数据的缓冲区ShortBuffer存储短整型数据的缓冲区IntBuffer存储整型数据的缓冲区LongBuffer存储长整型数据的缓冲区FloatBuffer存储单精度浮点型数据的缓冲区DoubleBuffer存储双精度浮点型数据的缓冲区
分配一个缓冲区的方式都高度一致:使用allocate(intcapacity)方法 。
例如需要分配一个1024大小的字节数组 , 代码就是下面这样子 。
ByteBufferbyteBuffer=ByteBuffer.allocate(1024);缓冲区读写数据的两个核心方法:
put():将数据写入到缓冲区中get():从缓冲区中读取数据缓冲区的重要属性:
capacity:缓冲区中最大存储数据的容量 , 一旦声明则无法改变limit:表示缓冲区中可以操作数据的大小 , limit之后的数据无法进行读写 。 必须满足limit<=capacityposition:当前缓冲区中正在操作数据的下标位置 , 必须满足position<=limitmark:标记位置 , 调用reset()将position位置调整到mark属性指向的下标位置 , 实现多次读取数据缓冲区为高效读写数据而提供的其它辅助方法:
flip():可以实现读写模式的切换 , 我们可以看看里面的源码publicfinalBufferflip(){limit=position;position=0;mark=-1;returnthis;}调用flip()会将可操作的大小limit设置为当前写的位置 , 操作数据的起始位置position设置为0 , 即从头开始读取数据 。
rewind():可以将position位置设置为0 , 再次读取缓冲区中的数据clear():清空整个缓冲区 , 它会将position设置为0 , limit设置为capacity , 可以写整个缓冲区更多的方法可以去查阅API文档 , 本文碍于篇幅原因就不贴出其它方法了 , 主要是要理解缓冲区的作用
我们来看一个简单的例子
publicClassMain{publicstaticvoidmain(String[]args){//分配内存大小为11的整型缓存区IntBufferbuffer=IntBuffer.allocate(11);//往buffer里写入2个整型数据for(inti=0;i<2;++i){intrandomNum=newSecureRandom().nextInt();buffer.put(randomNum);}//将Buffer从写模式切换到读模式buffer.flip();System.out.println("position>>"+buffer.position()+"limit>>"+buffer.limit()+"capacity>>"+buffer.capacity());//读取buffer里的数据while(buffer.hasRemaining()){System.out.println(buffer.get());}System.out.println("position>>"+buffer.position()+"limit>>"+buffer.limit()+"capacity>>"+buffer.capacity());}}执行结果如下图所示 , 首先我们往缓冲区中写入2个数据 , position在写模式下指向下标2 , 然后调用flip()方法切换为读模式 , limit指向下标2 , position从0开始读数据 , 读到下标为2时发现到达limit位置 , 不可继续读 。


推荐阅读