详细整理JavaNio原理(二)
关注并转发 , 每天发送更多java技术文章 。
咱们接着上回的知识点来讲:
通道的基本原理:
既可以从通道中读取数据 , 又可以写数据到通道 。 但流的读写通常是单向的 。 通道可以异步地读写 。 通道中的数据总是要先读到一个Buffer , 或者总是要从一个Buffer中写入 。正如上面所说 , 从通道读取数据到缓冲区 , 从缓冲区写入数据到通道 。 如下图所示:
FileChannel:从文件中读写数据 。 DatagramChannel:能通过UDP读写网络中的数据 。 SocketChannel:能通过TCP读写网络中的数据 。 ServerSocketChannel:可以监听新进来的TCP连接 , 像Web服务器那样 。 对每一个新进来的连接都会创建一个SocketChannel 。基本的Channel示例
下面是一个使用FileChannel读取数据到Buffer中的示例:
Java代码
RandomAccessFileaFile=newRandomAccessFile("data/nio-data.txt","rw");FileChannelinChannel=aFile.getChannel();ByteBufferbuf=ByteBuffer.allocate(48);intbytesRead=inChannel.read(buf);while(bytesRead!=-1){System.out.println("Read"+bytesRead);buf.flip();while(buf.hasRemaining()){System.out.print((char)buf.get());}buf.clear();bytesRead=inChannel.read(buf);}aFile.close();注意buf.flip()的调用 , 首先读取数据到Buffer , 然后反转Buffer,接着再从Buffer中读取数据 。 下一节会深入讲解Buffer的更多细节 。
缓冲区(Buffer)
JavaNIO中的Buffer用于和NIO通道进行交互 。 如你所知 , 数据是从通道读入缓冲区 , 从缓冲区写入到通道中的 。
缓冲区本质上是一块可以写入数据 , 然后可以从中读取数据的内存 。 这块内存被包装成NIOBuffer对象 , 并提供了一组方法 , 用来方便的访问该块内存 。
Buffer的基本用法
使用Buffer读写数据一般遵循以下四个步骤:
写入数据到Buffer调用flip()方法从Buffer中读取数据调用clear()方法或者compact()方法当向buffer写入数据时 , buffer会记录下写了多少数据 。 一旦要读取数据 , 需要通过flip()方法将Buffer从写模式切换到读模式 。 在读模式下 , 可以读取之前写入到buffer的所有数据 。
一旦读完了所有的数据 , 就需要清空缓冲区 , 让它可以再次被写入 。 有两种方式能清空缓冲区:调用clear()或compact()方法 。 clear()方法会清空整个缓冲区 。 compact()方法只会清除已经读过的数据 。 任何未读的数据都被移到缓冲区的起始处 , 新写入的数据将放到缓冲区未读数据的后面 。
下面是一个使用Buffer的例子:
Java代码
RandomAccessFileaFile=newRandomAccessFile("data/nio-data.txt","rw");FileChannelinChannel=aFile.getChannel();//createbufferwithcapacityof48bytesByteBufferbuf=ByteBuffer.allocate(48);intbytesRead=inChannel.read(buf);//readintobuffer.while(bytesRead!=-1){buf.flip();//makebufferreadyforreadwhile(buf.hasRemaining()){System.out.print((char)buf.get());//read1byteatatime}buf.clear();//makebufferreadyforwritingbytesRead=inChannel.read(buf);}aFile.close();Buffer的capacity,position和limit
缓冲区本质上是一块可以写入数据 , 然后可以从中读取数据的内存 。 这块内存被包装成NIOBuffer对象 , 并提供了一组方法 , 用来方便的访问该块内存 。
为了理解Buffer的工作原理 , 需要熟悉它的三个属性:
capacitypositionlimitposition和limit的含义取决于Buffer处在读模式还是写模式 。 不管Buffer处在什么模式 , capacity的含义总是一样的 。
这里有一个关于capacity , position和limit在读写模式中的说明 , 详细的解释在插图后面 。
position
当你写数据到Buffer中时 , position表示当前的位置 。 初始的position值为0.当一个byte、long等数据写到Buffer后 , position会向前移动到下一个可插入数据的Buffer单元 。 position最大可为capacity–1 。
当读取数据时 , 也是从某个特定位置读 。 当将Buffer从写模式切换到读模式 , position会被重置为0 。 当从Buffer的position处读取数据时 , position向前移动到下一个可读的位置 。
【详细整理JavaNio原理(二)】limit
在写模式下 , Buffer的limit表示你最多能往Buffer里写多少数据 。 写模式下 , limit等于Buffer的capacity 。
当切换Buffer到读模式时 , limit表示你最多能读到多少数据 。 因此 , 当切换Buffer到读模式时 , limit会被设置成写模式下的position值 。 换句话说 , 你能读到之前写入的所有数据(limit被设置成已写数据的数量 , 这个值在写模式下就是position)
Buffer的类型
JavaNIO有以下Buffer类型:
ByteBufferMappedByteBufferCharBufferDoubleBufferFloatBufferIntBufferLongBufferShortBuffer如你所见 , 这些Buffer类型代表了不同的数据类型 。 换句话说 , 就是可以通过char , short , int , long , float或double类型来操作缓冲区中的字节 。
MappedByteBuffer有些特别 , 在涉及它的专门章节中再讲 。
原文链接:
推荐阅读
- 精选整理42款菜肴推荐,做法简单,鲜香入味下酒下饭,越吃越香
- 整理几道菜肴送给你,家中待客家庭聚餐必备,家人吃的很满意
- 整理21款菜肴推荐,香辣开胃解馋解腻,喜欢就一起试试做吧
- 野菜馒头新做法, 比花卷包子都松软好吃, 讲解详细, 想不会都难
- 手把手教你做手抓饼,详细做法,新手看了想不会都难,和卖的一样好
- 中国红豆酥新做法, 不用烤箱烤, 照样酥脆掉渣, 做法简单讲解详细
- 整理27款佳肴分享,营养美味开胃下饭,学会为家人露一手吧
- 分享6道非常有特色的家常菜,有荤有素,有菜有汤,做法简单详细
- 梅菜扣肉(烧白)超详细方子
- 做青团,牢记一个小技巧,做好后翠绿不发黑!分享详细做法步骤
