关闭

Java字节数组处理工具类-Mina的IoBuffer封装

标签: javabuffer网络
2078人阅读 评论(0) 收藏 举报
分类:

Java字节数组处理工具类-Mina的IoBuffer封装

处理网络数据的项目中经常需要处理字节数据,Java的ByteBuffer很强大,但是Mina和Netty两个常用的网络通信框架都拥有自己的数据读取Buffer,分别是IoBuffer和ByteBuff,IoBuffer基于Java原生ByteBuffer封装而成,ByteBuff则是Netty自己独有的字节数据Buffer,可以实现零拷贝。

封装

由于项目中经常需要按int、short、byte[]、String数据类型读写数据协议,需要一个合适的数据处理buffer做协议的decode和encode,已经有IoBuffer和ByteBuff这样强大的轮子,无需再造。所以选择其中一种应用到项目中,ByteBuff功能强大,但是和Netty框架结合较深,如果用不到其中的通信功能,不妨直接使用Mina中的IoBuffer中的代码直接封装一个针对性强的数据处理Buffer。
例如:下面是一个针对IoBuffer的简单封装。

public class JBuffer {

  private IoBuffer buff;

  public JBuffer() {
    this.buff = IoBuffer.allocate(2048);
  }

  public JBuffer(int size) {
    this.buff = IoBuffer.allocate(size);
  }

  public JBuffer(IoBuffer buff) {
    this.buff = buff;
  }

  public JBuffer(byte[] bytes) {
    this.buff = IoBuffer.wrap(bytes);
  }

  public JBuffer mark() {
    this.buff.mark();
    return this;
  }

  public int markValue() {
    return this.buff.markValue();
  }

  public JBuffer reset() {
    this.buff.reset();
    return this;
  }

  public JBuffer flip() {
    this.buff.flip();
    return this;
  }

  public int remaining() {
    return this.buff.remaining();
  }

  public boolean hasRemain() {
    return this.buff.remaining() > 0;
  }

  public int position() {
    return this.buff.position();
  }

  public void position(int newPosition) {
    this.buff.position(newPosition);
  }

  public void clear() {
    this.buff.clear();
  }

  public void putByte(byte a) {
    this.buff.put(a);
  }

  public void putShort(short a) {
    this.buff.putShort(a);
  }

  public void putBytes(byte[] a) {
    this.buff.put(a);
  }

  public void putInt(int a) {
    this.buff.putInt(a);
  }

  public void putString(String str) {
    try {
      this.buff.putString(str, Charset.forName("GBK").newEncoder());
    } catch (CharacterCodingException e1) {
      e1.printStackTrace();
    }
  }

  public void putString(String str, int len) {
    try {
      this.buff.putString(str, len, Charset.forName("GBK").newEncoder());
    } catch (CharacterCodingException e1) {
      e1.printStackTrace();
    }
  }

  public byte get(int index) {
    return this.buff.get(index);
  }

  public byte getByte() {
    return this.buff.get();
  }

  public byte[] getBytes(int len) {
    byte[] data = new byte[len];
    this.buff.get(data);
    return data;
  }

  public byte[] getBytes() {
    byte[] data = new byte[this.buff.limit() - this.buff.position()];
    this.buff.get(data);
    return data;
  }

  public int getInt() {
    return this.buff.getInt();
  }

  public short getShort() {
    return this.buff.getShort();
  }

  public String getString() {
    try {
      String str = this.buff.getString(Charset.forName("GBK").newDecoder());
      return str;
    } catch (CharacterCodingException e) {
      e.printStackTrace();
      return "";
    }
  }

  public String getString(int len) {
    try {
      String str = this.buff.getString(len, Charset.forName("GBK").newDecoder());
      return str;
    } catch (CharacterCodingException e) {
      e.printStackTrace();
      return "";
    }
  }

  public byte[] array() {
    int pos = this.buff.position();
    byte[] data = new byte[pos];
    this.buff.position(0);
    this.buff.get(data);
    return data;
  }
}

上面的代码主要用于从数据buffer中读取和输入不同类型的数据,包括byte、bytes、short、int、String。

应用

简单写个用例测试一下:

  @Test public void testBuffer() {
    String str = "1234";
    JBuffer buffer = new JBuffer();
    buffer.putString(str, 10);     // 31 32 33 34 00 00 00 00 00 00 (10个字节)
    buffer.putShort((short) 100); // 00 64 (2个字节)
    System.out.println("数据长度:" + buffer.position());
    buffer.flip();
    System.out.println("获取字符串:" + buffer.getString() + " position:" + buffer.position());//取走31 32 33 34 00(共5个字节)其中00为结束符'\0'
    System.out.println("取走为0数据:" + buffer.getBytes(5).length + " position:" + buffer.position());//取走00 00 00 00 00(5个字节)
    System.out.println("获取short:" + buffer.getShort() + " position:" + buffer.position());//取走 00 64(2个字节)
  }

输出:

数据长度:12
获取字符串:1234 position:5
取走为0数据:5 position:10
获取short:100 position:12

非常简单的数据读取操作,short和int等比较好理解,输入字符串String的时候如果在putString(str, len)加第二个参数len,表示如果字符串字节数小于len会在buffer里填充0x00,而getString()会读到有’\0’的位置,若没有’\0’则会读到数据结尾。
OK,有其它好的工具欢迎留言分享~

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:112421次
    • 积分:1679
    • 等级:
    • 排名:千里之外
    • 原创:31篇
    • 转载:12篇
    • 译文:6篇
    • 评论:21条
    博客专栏
    文章分类
    最新评论