zoukankan      html  css  js  c++  java
  • Java ByteBuffer用法总结

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

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

    SocketChannel采用的是非阻塞异步读取流数据,在读取的时候,通常是

    1. ByteBuffer.clear();
    2. SocketChannel.read(ByteBuffer);

    如果流中有数据,就会把数据从position开始读到ByteBuffer中,在读取之前ByteBuffer的clear操作会把 position置为0,limit置为capability,也就是相当于清空了之前的内容,但是ByteBuffer中数组的内容在read之前是没 有改变的.

    read之后,通常就是开始从ByteBuffer中提取读到的数据,如果你的数据是以自己定义的数据包的格式进行发送的,那你还需要判断是否读到 了数据包的结尾,因为对流数据本身来说是没有结尾这一说的。在提取数据之前,要先把position放到开始读取时的位置,把limit放到当前位置,所 以要flip一下,表示从position到limit的位置都是需要的数据。

    1. ByteBuffer.flip();
    2. while(ByteBuffer.hasRemaining()){
    3. byte c=ByteBuffer.get();
    4. if(b == PACKAGE_END){
    5. //you can return the package here
    6. }else{
    7. //you can append the byte here.like StringBuilder.append().
    8. }
    9. }

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

    1. if(!ByteBuffer.hasRemaining){
    2. ByteBuffer.clear();
    3. SocketChannel.read(ByteBuffer);
    4. }

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

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

  • 相关阅读:
    2011年需要关注的9大编程语言 狼人:
    微软在华推广Win7拒绝“黑屏” 狼人:
    ifanr访谈:GuruDigger — Web工程师排排坐 狼人:
    10种破除网页设计师障碍的实用方法 狼人:
    英特尔CEO:微软Windows 7是PC更新的催化剂 狼人:
    Windows 7市场份额突破25% XP持续下滑 狼人:
    Office Web Apps中文版正式上线 狼人:
    机器学习实现线性梯度算实现octave
    管理系统数据库sql server 数据库管理
    缓存代码sencha Touch 缓存问题解析
  • 原文地址:https://www.cnblogs.com/yuxiang204/p/3395506.html
Copyright © 2011-2022 走看看