Java ByteBuffer用法总结

最近用SocketChannel进行网络编程比较多,中间也遇到了几个问题,出现的bug也主要来自于对于ByteBuffer的使用不当。如今终于调通了,对ByteBuffer及Socket网络编程也有了更深的认识,特此总结一下。 编程

对于ByteBuffer主要须要注意的是几个标志的含义:position,limit,capability,mark.几个操做的影响:flip(),clear(),rewind().还有就是在读取或者写入时,标志的变化,好比get()方法致使position加1. 数组

SocketChannel采用的是非阻塞异步读取流数据,在读取的时候,一般是 网络

ByteBuffer.clear();
SocketChannel.read(ByteBuffer); app

若是流中有数据,就会把数据从position开始读到ByteBuffer中,在读取以前ByteBuffer的clear操做会把position置为0,limit置为capability,也就是至关于清空了以前的内容,可是ByteBuffer中数组的内容在read以前是没有改变的. 异步

read以后,一般就是开始从ByteBuffer中提取读到的数据,若是你的数据是以本身定义的数据包的格式进行发送的,那你还须要判断是否读到了数据包的结尾,由于对流数据自己来讲是没有结尾这一说的。在提取数据以前,要先把position放到开始读取时的位置,把limit放到当前位置,因此要flip一下,表示从position到limit的位置都是须要的数据。 工具

ByteBuffer.flip();
while(ByteBuffer.hasRemaining()){
byte c=ByteBuffer.get();
if (b == PACKAGE_END) {
//you can return the package here
}else{
//you can append the byte here.like StringBuilder.append().
}
}
ui

这样以来也存在一个问题,当一次读到的ByteBuffer不包含完整的数据包或者包含多个数据包.那么就须要在下一次继续把这些包分拆出来.那么在读取数据的代码处就能够改成,这样就把以前读取到的未完整的包保留了下来: 设计

if(!ByteBuffer.hasRemaining){
ByteBuffer.clear();
SocketChannel.read(ByteBuffer);
}
ip

另一个可能会用到的操做就是ByteBuffer.rewind(),他会把position置为0,limit保持不变,能够用于重复读取一段数据. get

ByteBuffer是nio中一个很是方便的工具.设计思想也很是值得借鉴.

相关文章
相关标签/搜索