专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  项目终于用上了 Spring 状态机,太优雅了! ·  4 小时前  
芋道源码  ·  好记性不如烂笔头:Spring(春天) ·  昨天  
芋道源码  ·  如何为开放平台设计一个安全好用的OpenApi ·  昨天  
芋道源码  ·  能在一家不到 20 人的 IT ... ·  2 天前  
芋道源码  ·  疯传Java界,堪称最强! ·  2 天前  
51好读  ›  专栏  ›  ImportNew

Netty 精粹之玩转 NIO 缓冲区

ImportNew  · 公众号  · Java  · 2017-03-28 12:00

正文

请到「今天看啥」查看全文



public int read(ByteBuffer dst) throws IOException;

public int write(ByteBuffer src) throws IOException;


从上面的接口我们可以看到Channel和ByteBuffer之间发生的两个基本行为,即readding/writing。无论是对文件(FileChannel)还是对网络(SocketChannel)的读写,他们都会去实现这两个基本行为。好了,我们已经从总体上认识ByteBuffer在JAVA NIO所处的位置和担当的角色了,下面我们继续深入一点认识ByteBuffer。


ByteBuffer有四个重要的属性,分别为:mark、position、limit、capacity,和两个重要方法分别为:flip和clear。ByteBuffer的底层存储结构对于堆内存和直接内存分别表现为堆上的一个byte[]对象和直接内存上分配的一块内存区域。既然是一块内存区域,那么我们就可以对其进行基于字节的读和写,而ByteBuffer的四个int类型的属性则是指向这块区域的指针:


  1. position:读写指针,代表当前读或写操作的位置,这个值总是小于等于limit的。


  2. mark:在使用ByteBuffer的过程中,如果想要记住当前的position,则会将当前的position值给mark,让需要恢复的时候,再将mark的值给position。


  3. capacity:代表这块内存区域的大小。


  4. limit:初始的Buffer中,limit和capacity的值是相等的,通常在clear操作和flip操作的时候会对这个值进行操作,在clear操作的时候会将这个值和capacity的值设置为相等,当flip的时候会将当前的position的值给limit,我们可以总结在写的时候,limit的值代表最大的可写位置,在读的时候,limit的值代表最大的可读位置。clear是为了写作准备、flip是为了读做准备。


ByteBuffer指针示意图


在JAVA NIO中,原生的ByteByffer家族成员很简单,主要是HeapByteBuffer、DirectByteBuffer和MappedByteBuffer:


  1. HeapByteBuffer是基于堆上字节数组为存储结构的缓冲区。


  2. DirectByteBuffer是基于直接内存上的内存区域为存储结构的缓冲区。


  3. MappedByteBuffer主要是文件操作相关的,它提供了一种基于虚拟内存映射的机制,使得我们可以像操作文件一样来操作文件,而不需要每次将内容更新到文件之中,同时读写效率非常高。


Netty之ByteBuf


相比于ByteBuffer的读写指针position,ByteBuf提供了两个指针readerIndex和writeIndex来分别指向读的位置和写的位置,不需要每次为读写做准备,直接设置读写指针进行读写操作即可。我们看看处于中间状态的状态:








请到「今天看啥」查看全文