ChannelBuffer是Netty中比较常用的一个类,其功能类似于字符数组,可以对其进行读写操作。
ChannelBuffer的模型图如下:
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
| | (CONTENT) | |
+-------------------+------------------+------------------+
| | | |
如上图所示,一个ChannelBuffer被划分为三个部分:
1.discardable:表示已经读过的内容缓冲区
2.readable:表示可读的内容缓冲区
3.writable:表示可写的内容缓冲区
ChannelBuffer的这三个缓冲区由2个内部控制指针来控制:
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,表示写入下标越界,会抛出
返回可写入的字节数(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()
测试代码如下:
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
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
返回可写入的字节数(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