您的位置:首页 > 移动开发 > Android开发

封装android 通讯使用二进制进行数据交换 2个必要的读取,写入操作

2015-01-30 11:43 567 查看
我们先来分析下为什么使用2进制来进行通讯中的数据交换:

一 优点:

1、节省数据流量消耗;一个byte有 8个bit能代表好多意思呢。

2、增加可靠性;数据被拦截,对方无文档也解不开这数据到底描述的是什么。

二 缺点:

1、开发阶段,出现bug 不好排除bug,没字符串来的直观.

2、数据粘包,串包,一个字节出错,全盘皆错。

但是这2个缺点在技术上是可避免的。下面介绍2个读取byte 写byte的2个工具类

ReadBuffer:

package io.xilnk.wifi.sdk.buffer;

import io.xilnk.wifi.sdk.util.XTUtils;

/**
 * 读取Buff使用
 * 
 * @author Liuxy
 * @2015年1月14日上午11:51:09 </br>
 * @explain
 */
public class ReadBuffer {
    // 当前读取数据的索引
    private int index;
    // 数据
    private byte[] buf;

    public ReadBuffer(byte[] bys, int offset) {
	buf = bys;
	this.index = offset;
    }

    /**
     * 设置偏移量.不推荐使用
     *
     * @deprecated
     * @param index
     */
    public void setIndex(int offset) {
	this.index = offset;
    }

    /**
     * 读取结束
     */
    public void finsh() {
	buf = null;
	index = 0;
    }

    /**
     * 返回所有的byte[]
     * 
     * @return
     */
    public byte[] array() {
	return buf;
    }

    /**
     * 每次读取,需要把当前索引值加起来
     * 
     * @param count
     */
    private void addIndex(int count) {
	index += count;
	if (buf.length == index) {
	    finsh();
	}
    }
<pre name="code" class="java">    /**
     * 获取当前的偏移量
     * 
     * @return
     */
public int getOffset() {return index; } /** * 读取一个字节布尔 * * @return */ public boolean readBoolean() {byte b = buf[index];addIndex(1);// 不等于0就是true,等于0为falsereturn b != 0; } @Override public String toString() {// TODO Auto-generated method
stubreturn "当前索引: " + index + " 数据总长度 :" + buf.length + " " + buf; } /** * 读取一个byte * * @return */ public byte readByte() {byte b = buf[index];addIndex(1);return b; } /** * 读取剩下的byte[] * * @return */ public byte[] readEndByte() {byte[] bs = new byte[buf.length
- index];System.arraycopy(buf, index, bs, 0, bs.length);index += bs.length;finsh();return bs; } /** * 读取4个字节的int * * @return */ public int readInt() {byte[] b = new byte[4];System.arraycopy(buf, index, b, 0, b.length);addIndex(b.length);return XTUtils.bytesToInt2(b);
} /** * 读取2个字节的Short * * @return */ public short readShort() {short s = XTUtils.byte2Short(buf, index);addIndex(2);return s; } /** * 读取指定大小的byte[] * * @return */ public byte[] readBytes(int size) {byte[] bs = new byte[size];System.arraycopy(buf, index, bs,
0, bs.length);addIndex(size);return bs; }}



WriteBuffer:

package io.xilnk.wifi.sdk.buffer;

import io.xilnk.wifi.sdk.util.XTUtils;

/**
 * 写数据
 * 
 * @author Liuxy
 * @2015年1月14日上午11:51:58 </br>
 * @explain
 */
public class WriteBuffer {
    // 当前的数据
    private byte[] buf;
    // 当前写入的索引
    private int index;

    /**
     * 
     * @param size
     *            需要写入多大数据
     */
    public WriteBuffer(int size) {
	buf = new byte[size];
	index = 0;
    }

    /**
     * 写2个字节short
     * 
     * @param srt
     */
    public void writeShort(short srt) {

	byte[] srtbyte = XTUtils.shortToByteArray(srt);
	writeBytes(srtbyte);
    }

    /**
     * 写2个字节short
     * 
     * @param srt
     */
    public void writeShort(int srt) {
	writeShort((short) srt);
    }

    /**
     * 获取byte array
     * 
     * @return
     */
    public byte[] array() {
	return buf;
    }

    /**
     * 写4个字节int
     * 
     * @param srt
     */
    public void writeInt(int i) {
	byte[] srtbyte = XTUtils.intToByteArray(i);
	writeBytes(srtbyte);
    }

    /**
     * 写入byte[]
     * 
     * @param srt
     */
    public void writeBytes(byte[] data) {
	int len = data.length;
	System.arraycopy(data, 0, buf, index, len);
	index += len;
    }

    // public byte[] getBuf() {
    //
    // return buf;
    // }
    /**
     * 返回当前写的索引值
     * 
     * @return
     */
    public int getIndex() {
	return index;

    }

    /**
     * 写入1个字节的布尔
     * 
     * @param srt
     */
    public void writeBoolean(boolean b) {
	byte by = 0;
	if (b) {
	    by = 1;
	} else {
	    by = 0;
	}
	writeByte(by);
    }
    /**
     * 写入1个字节的byte
     * 
     * @param srt
     */
    public void writeByte(int b) {
	writeByte((byte) b);
    }

    public void writeByte(byte b) {
	buf[index] = b;
	index++;
    }

//    public static WriteBuffer newByteBuf(int size) {
//	return new WriteBuffer(size);
//    }
}


最后奉上 byte 转换从几大基本数据类型的常用工具:

/**
     * byte[] 转int 高位在前,低位在后
     * 
     * @param src
     * @return
     */
    public static int bytesToInt2(byte[] src) {
	int value;
	value = (int) (((src[0] & 0xFF) << 24) | ((src[0 + 1] & 0xFF) << 16)
		| ((src[0 + 2] & 0xFF) << 8) | (src[0 + 3] & 0xFF));
	return value;
    }

    /**
     * 将16位的short转换成byte数组
     * 
     * @param s
     *            short
     * @return byte[] 长度为2
     * */
    public static byte[] shortToByteArray(short s) {
	byte[] targets = new byte[2];
	for (int i = 0; i < 2; i++) {
	    int offset = (targets.length - 1 - i) * 8;
	    targets[i] = (byte) ((s >>> offset) & 0xff);
	}
	return targets;
    }

    /**
     * 将32位整数转换成长度为4的byte数组
     * 
     * @param s
     *            int
     * @return byte[]
     * */
    public static byte[] intToByteArray(int i) {
	byte[] result = new byte[4];
	result[0] = (byte) ((i >> 24) & 0xFF);
	result[1] = (byte) ((i >> 16) & 0xFF);
	result[2] = (byte) ((i >> 8) & 0xFF);
	result[3] = (byte) (i & 0xFF);
	return result;
    }

    /**
     * 把byte转化成 二进制.
     * 
     * @param aByte
     * @return
     */
    public static String getBinString(byte aByte) {
	String out = "";
	int i = 0;
	for (i = 0; i < 8; i++) {
	    int v = (aByte << i) & 0x80;
	    v = (v >> 7) & 1;
	    out += v;
	}
	return out;
    }
   /**
     * buf转 String
     * 
     * @param buf
     * @return
     */
    public static String buf2String(byte[] buf) {
	return new String(buf, Charset.forName(ENCODING));
    }

    /**
     * String 转 buf
     * 
     * @param buf
     * @return
     */
    public static byte[] string2buf(String text) {

	return text.getBytes(Charset.forName(ENCODING));
    }

    /**
     * 截取 byte
     * 
     * @param src
     *            源数据
     * @param off
     *            偏移量
     * @param len
     *            长度
     * @return
     */
    public static byte[] subBytes(byte[] bytes, int offset, int len) {
	byte[] b = new byte[len - offset];
	System.arraycopy(bytes, offset, b, 0, len);
	return b;
    }
/**
     * 无符号的short
     * 
     * @param s
     * @return
     */
    public static int UnsignedShort(int s) {
	if (s < 0) {
	    s = 65536 + s;
	}
	return s;
    }


使用方法 跟netty框架的 ByteBuf 差不多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: