原文出处:http://blog.csdn.net/lxgwm2008/article/details/7735231


ChannelBuffer是Netty中比较常用的一个类,其功能类似于字符数组,可以对其进行读写操作。

ChannelBuffer的模型图如下:

 +-------------------+------------------+------------------+
 | discardable bytes |  readable bytes  |  writable bytes  |
 |                   |     (CONTENT)    |                  |
 +-------------------+------------------+------------------+
 |                   |                  |                  |

 0      <=      readerIndex   <=   writerIndex    <=    capacity



如上图所示,一个ChannelBuffer被划分为三个部分:

1.discardable:表示已经读过的内容缓冲区

2.readable:表示可读的内容缓冲区

3.writable:表示可写的内容缓冲区

ChannelBuffer的这三个缓冲区由2个内部控制指针来控制:

readerIndex:控制读缓冲区首地址

writerIndex:控制写缓冲区首地址

因此,ChannelBuffer提供的大部分操作都是围绕readerIndex和writerIndex来进行的。



ChannelBuffer的常用方法如下:

1、read()/skip()

从readerIndex读出或跳过指定数目的字节,同时readerIndex = readerIndex + byteNumber.如果readerIndex > capacity,表示读取下标越界,会抛出

IndexOutOfBoundsException异常

readable():boolean

如果buffer有可读内容(此时writerIndex > readerIndex),则返回true,否则返回false

readerIndex():int

返回readerIndex

readableBytes():int

返回可读的字节数目(writerIndex - readerIndex)

2、write();

写入指定数目的字节,同时writerIndex = writerIndex + byteNumber. 如果writerIndex > capacity,表示写入下标越界,会抛出

IndexOutOfBoundsException异常


writable():boolean

如果buffer有可写入空间(此时writerIndex < capacity),则返回true,否则返回false。


writerIndex(): int

返回writerIndex


writeableIndex():int
返回可写入的字节数(capacity - writerIndex)。

3、discardReadBytes()

丢弃已读的内容。其执行过程如下:

调用discardReadBytes()之前:

+-------------------+------------------+------------------+
| discardable bytes |  readable bytes  |  writable bytes  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity

调用 discardReadBytes()方法后

+------------------+--------------------------------------+
|  readable bytes  |    writable bytes (got more space)   |
+------------------+--------------------------------------+
|                  |                                      |
readerIndex (0) <= writerIndex (decreased)    <=      capacity

4、clear()
丢弃所有的数据,并将readerIndex和writerIndex重置为0。

调用clear()之前
 +-------------------+------------------+------------------+
 | discardable bytes |  readable bytes  |  writable bytes  |
 +-------------------+------------------+------------------+
 |                   |                  |                  |
 0      <=      readerIndex   <=   writerIndex    <=    capacity

 

 调用clear()之后

 +---------------------------------------------------------+ |             
                 writable bytes (got more space)             | 
 +---------------------------------------------------------+ |                                                         | 
0 = readerIndex = writerIndex            <=            capacity

5、

markReaderIndex()
markWriterIndex()


保存readerIndex或writerIndex的状态

6、

resetReaderIndex()

resetWriterIndex()


重置readerIndex或writerIndex为最后一次保存的状态,如果没有保存过,则置为0

7、

duplicate()

slice()


拷贝和源目标共享buffer的数据区域,但是拷贝有自己的readerIndex和writerIndex以及markIndex,实际上只是拷贝了控制指针,数据区还是与源buffer共享。

8、copy()

拷贝整个buffer,包括控制指针和数据区




测试代码如下:

package test;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;

public class ChannelBufferTest {

    /**
     *
     * @author lengxue
     * @date 11 Jul 2012 09:05:10
     * @param args
     * @note
     */
    public static void main( String[] args ) {
        // TODO Auto-generated method stub
        ChannelBuffer buffer = ChannelBuffers.buffer( 10 );
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
        
        buffer.writeInt( 10 );
        System.out.println("after write one integer");
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));

        buffer.writeInt( 10 );
        System.out.println("after write two integer");
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
        
        int i = buffer.readInt( );
        System.out.println("after read one integer: " + i);
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
        
        buffer.discardReadBytes( );
        System.out.println("after discard read bytes");
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
        
        buffer.resetReaderIndex( );
        System.out.println("after reset reader index");
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
        
        buffer.resetWriterIndex( );
        System.out.println("after reset writer index");
        System.out.println("readable bytes: " + buffer.readableBytes( ));
        System.out.println("readable index: " + buffer.readerIndex( ));
        System.out.println("writable bytes: " + buffer.writableBytes( ));
        System.out.println("writable index: " + buffer.writerIndex( ));
    }

}

结果输出如下:

readable bytes: 0
readable index: 0
writable bytes: 10
writable index: 0
after write one integer
readable bytes: 4
readable index: 0
writable bytes: 6
writable index: 4
after write two integer
readable bytes: 8
readable index: 0
writable bytes: 2
writable index: 8
after read one integer: 10
readable bytes: 4
readable index: 4
writable bytes: 2
writable index: 8
after discard read bytes
readable bytes: 4
readable index: 0
writable bytes: 6
writable index: 4
after reset reader index
readable bytes: 4
readable index: 0
writable bytes: 6
writable index: 4
after reset writer index
readable bytes: 0
readable index: 0
writable bytes: 10
writable index: 0