秋风醉了 发表于4年前
  • 发表于 4年前
  • 阅读 4129
  • 收藏 0
  • 点赞 0
  • 评论 0


摘要: Netty_ByteBuf的基本用法(一)

Netty s buffer API has two interfaces: 

  • ByteBuf 

  • ByteBufHolder

ByteBuf - The byte data container

Whenever(每当)  you  need  to  interact(相互作用)  with  a  remote  peer  such  as  a  database,  the  communication needs to be done in bytes. For this and other reasons an efficient(高效), convenient, and easy-to-use data structure  is required, and Netty's ByteBuf implementation  meets these requirements and more, making it an ideal data container, optimized(最佳的) for holding and interacting with bytes. ByteBufis a data container that allows you to add/get bytes from it in an efficient way. To make it easier to operate, it uses two indices: one for reading and one for writing. This allows you to read data out of them in a sequential way and "jump" back to read it again. All you need to do is adjust(调整) the reader index and start the read operation again.

How it works

After  something  is  written  to  the ByteBuf, its writerIndex is  increased  by  the  amount  of bytes written. After you start to read bytes, its readerIndexis increased. You can read bytes until  the writerIndex and readerIndex are  at  the  same position.  The  ByteBuf then becomes  unreadable,  so  the  next  read  request  triggers(触发) an IndexOutOfBoundsException similar to what you ve seen when trying to read beyond the capacity of an array. Calling any of the buffer s methods beginning with "read" or "write" automatically(自动的) advances the  reader  and  writer  indexes  or  you. There  are  also  relative  operations  to set  and   get bytes. These don t move the indexes but operate on the relative(相对的) index that was given. A ByteBuf may  have  a maximum  capacity(容量)  to  set  an  upper  limit(上限)  to  the  maximum  data  it can hold, trying to move the writer index beyond this capacity will result in an exception. The default limit is Integer.MAX_VALUE. 

Figure 5.2 shows how a ByteBufis laid out. 


As  Figure  5.1  shows,  a ByteBuf is  similar  to  a  byte  array,  the  most  notable(显著的)  difference  being the  addition  of  the read  and  write  indices  which  can  be used  to control  access  to  the  buffer's data. You ll  learn  more  about  the  operations  that can  be  performed  on  a ByteBuf in  a  later section. For now, keep this in mind and let s review the different types of ByteBufthat you ll most likely use. 

Different types of ByteBuf

There are three different types of ByteBuf you ll encounter when using Netty (there are more, but these are used internally). You may end up implementing your own, but this is out of scope here. Let s look at the provided types that you are most likely interested in. 


The  most  used type is the ByteBuf that stores  its data  in the heap space(堆内存) of the JVM.  This  is done  by  storing  it  in a  backing  array.  This  type  is  fast  to  allocate  and  also  de-allocate  when you 're  not  using  a  pool.  It  also  offers  a  way  to directly  access  the  backing  array,  which  may make it easier to interact with legacy(遗留的) code . 


Another ByteBuf implementation  is  the   direct  one.Direct  means  that  it  allocates  the memory  directly,  which  is  outside  the heap . You won' t  see  its memory  usage  in  your  heap space. You must take this into account when calculating the maximum amount of memory your application will use and how to limit it, as the max heap size won' t be enough. Direct buffers on the  other side  are  optimal(最佳的,最优的) when  it s  time  to transfer  data  over  a  socket. In  fact,  if  you  use a nondirect  buffer,  the  JVM will  make  a copy  of  your  buffer  to  a  direct  buffer internally(实质上)  before sending it over the socket. The  down  side  of  direct buffers is  that they' re  more expensive  to  allocate(分配)  and  de-allocate compared to heap buffers. This is one of the reasons why Netty supports pooling, which makes this problem disappear. Another possible down side can be that you' re no longer able to access the data  via the  backing  array,  so  you' ll  need  to  make  a copy  of  the  data  if  it  needs  to  work with legacy code that requires this. The following listing shows how you can get the data in an array and call your method even without the ability to access the backing array directly. 


The  last ByteBuf implementation  you  may  be  confronted(面对的)  with  is  the  CompositeByteBuf. This  does  exactly what its  name  says;  it  allows  you  to  compose different ByteBuf instances and provides a view over them. The good thing is you can also add and remove them on-the-fly(在传输过程中), so it s kind of like a List. If you ve ever worked with the JDK's ByteBuffer you' ve most likely missed such a feature there. As the CompositeByteBufis just a view over others, the hasArray() method  will  return false  because  it may  contain  several  ByteBuf instances  of both direct and nondirect types. For  example,  a  message  could  be  composed  of  two parts:  header and  body.  In  a modularized application, the two parts could be produced by different modules and assembled later when  the  message  is  sent  out.  Also,  you may  use  the  same  body  all  the  time  and  just change the header. So it would make sense here to not allocate a new buffer every time. This  would  be  a  perfect fit  for  a CompositeByteBuf as  no  memory  copy  will be  needed and the same API could be used as with non-composite buffers. 

Figure  5.2  shows  how  a CompositeByteBuf would  be  used  to  compose(组成)  the  header  and body.


  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 220
博文 583
码字总数 411142
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
* 支付类型