android 字节数据的转换与处理

现在android越来越多用于一些物联网IOT方面的应用,那么久难免会需要处理二进制数据,一般IOT数据通信协议为了减少通信数据量,都会使用字节数据或位标志。但是android的java下,没有无符号数据概念,所以处理起来会有些繁琐。
我依据平时数据传输所需要的应用,写了一个类,可以用来处理相应的无符号数据。
解决了几个问题:

  1. byte[]数组在建立和初始化时,一定要强制转换。
  2. 2个字节组合成一个16位无符号或有符号的数据计算。
  3. 4个字节组合成一个32位无符号或有符号的数据计算。
  4. 打印16进制形式的数组,方便调试,和对照协议进行查看。
    以上表达不全面,直接上代码,后面有应用的例子:
public class Bytes{    /**     * 字节数组的容量     */    int mCap = 0;    /**     * 实际字节数组容器     */    byte[] mBytes;    /**     * 通过设定字节数组容量来构建对象     * @param cap   int 字节数组容量     */    public Bytes(int cap) {        mBytes = new byte[cap];        mCap = cap;    }    /**     * 默认构建字节数组为容量为4     */    public Bytes() {        mBytes = new byte[4];        mCap = 4;    }    /**     * 通过已有byte[]进行构建对象,同时设定容器容量     * @param mBytes    byte[]     */    public Bytes(byte[] mBytes) {        this.mBytes = mBytes;        mCap = mBytes.length;    }    /**     * 通过已有int[]进行构建对象,同时设定容器容量,会把int型强制转换为byte型,超过范围都按0xff设定     * @param mInts int[]     */    public Bytes(int[] mInts) {        mCap = mInts.length;        mBytes = new byte[mCap];        for (int i = 0; i < mCap; i++) {            if (mInts[i] > 255) {                this.mBytes[i] = (byte) 255;            } else {                this.mBytes[i] = (byte) (mInts[i] & 0xff);            }        }    }    /**     * 从容器中指定偏移位置读取16位的无符号整形,大端模式     * @param offset    int 容器偏移量     * @return          int 返回16位无符号整形,大端模式     */    public int readUInt16BE(int offset) {        int res = 0;        if (mBytes != null && (mCap-offset) >= 2) {            res = ((mBytes[offset] & 0xff) << 8) + (mBytes[offset + 1] & 0xff);        }        return res;    }    /**     * 从容器起始位置读取16位无符号整形,大端模式     * @return int  返回16位无符号整形,大端模式     */    public int readUInt16BE() {        return readUInt16BE(0);    }    /**     * 从容器中指定偏移位置读取16位的无符号整形,小端模式     * @param offset    int 容器偏移量     * @return          int 返回16位无符号整形,小端模式     */    public int readUInt16LE(int offset) {        int res = 0;        if (mBytes != null && (mCap-offset) >= 2) {            res = ((mBytes[offset + 1] & 0xff) << 8) + (mBytes[offset] & 0xff);        }        return res;    }    /**     * 从容器中指定偏移位置读取16位的无符号整形,小端模式     * @return  int 返回16位无符号整形,小端模式     */    public int readUInt16LE() {        return readUInt16LE(0);    }    /**     * 从容器中指定偏移位置读取32位的无符号整形,大端模式     * @param offset    int     容器偏移量     * @return          long    返回32位无符号整形,大端模式     */    public long readUInt32BE(int offset) {        long res = 0;        if (mBytes != null && (mCap-offset) >= 4) {            res = ((mBytes[offset] & 255L) << 24) + ((mBytes[offset + 1] & 255L) << 16) + ((mBytes[offset + 2] & 0x255L) << 8) + (mBytes[offset + 3] & 0x255L);        }        return res;    }    /**     * 从容器中指定偏移位置读取32位的无符号整形,大端模式     * @return  long    返回32位无符号整形,大端模式     */    public long readUInt32BE() {        return readUInt32BE(0);    }    /**     * 从容器中指定偏移位置读取32位的无符号整形,小端模式     * @param offset    int     容器偏移量     * @return          long    返回32位无符号整形,小端模式     */    public long readUInt32LE(int offset) {        long res = 0;        if (mBytes != null && (mCap-offset) >= 4) {            res = ((mBytes[offset + 3] & 255L) << 24) + ((mBytes[offset + 2] & 255L) << 16) + ((mBytes[offset + 1] & 0x255L) << 8) + (mBytes[offset] & 0x255L);        }        return res;    }    /**     * 从容器中指定偏移位置读取32位的无符号整形,小端模式     * @return  long    返回32位无符号整形,小端模式     */    public long readUInt32LE() {        return readUInt32LE(0);    }    /**     * 从容器中指定偏移位置读取16位的有符号整形,大端模式     * @param offset    int 容器偏移量     * @return          int 返回16位有符号整形,大端模式     */    public int readInt16BE(int offset) {        int res = 0;        if (mBytes != null && (mCap-offset) >= 2) {            res = (mBytes[offset] << 8) + mBytes[offset+1];        }        return res;    }    /**     * 从容器中指定偏移位置读取16位的有符号整形,大端模式     * @return  int 返回16位有符号整形,大端模式     */    public int readInt16BE(){        return readInt16BE(0);    }    /**     * 从容器中指定偏移位置读取16位的有符号整形,小端模式     * @param offset    int 容器偏移量     * @return          int 返回16位有符号整形,小端模式     */    public int readInt16LE(int offset) {        int res = 0;        if (mBytes != null && (mCap-offset) >= 2) {            res = (mBytes[offset+1] << 8) + mBytes[offset];        }        return res;    }    /**     * 从容器中指定偏移位置读取16位的有符号整形,小端模式     * @return  int 返回16位有符号整形,小端模式     */    public int readInt16LE(){        return readInt16LE(0);    }    /**     * 从容器中指定偏移位置读取32位的有符号整形,大端模式     * @param offset    int     容器偏移量     * @return          long    返回32位有符号整形,大端模式     */    public long readInt32BE(int offset) {        long res =0;        if (mBytes != null && (mCap-offset) >= 4) {            res = (mBytes[offset] << 24) + (mBytes[offset+1] << 16) + (mBytes[offset+2] << 8) + mBytes[offset+3];        }        return res;    }    /**     * 从容器中指定偏移位置读取32位的有符号整形,大端模式     * @return  long    返回32位有符号整形,大端模式     */    public long readInt32BE(){        return readInt32BE(0);    }    /**     * 从容器中指定偏移位置读取32位的有符号整形,小端模式     * @param offset    int     容器偏移量     * @return          long    返回32位有符号整形,小端模式     */    public long readInt32LE(int offset) {        long res =0;        if (mBytes != null && (mCap-offset) >= 4) {            res = (mBytes[offset+3] << 24) + (mBytes[offset+2] << 16) + (mBytes[offset+1] << 8) + mBytes[offset];        }        return res;    }    /**     * 从容器中指定偏移位置读取32位的有符号整形,小端模式     * @return  long 返回32位有符号整形,小端模式     */    public long readInt32LE(){        return readInt32LE(0);    }    /**     * 获得容器容量     * @return  int 容器容量     */    public int length() {        return mCap;    }    /**     * 连接另一个byte[],可设定来源数据的起始位置,以及长度,也可设定目标数据的连接起始位置     * @param offsetT   int     目标数据的连接起始位置     * @param b         byte[]  来源数据     * @param offset    int     来源数据起始位置     * @param length    int     来与数据长度     */    public void cat(int offsetT, byte[] b, int offset, int length) {        byte[] tmp = mBytes;        mCap = offsetT + length;        mBytes = new byte[mCap];        for (int i = 0; i < offsetT; i++) {            mBytes[i] = tmp[i];        }        for (int i = 0; i < length; i++) {            mBytes[i + offsetT] = b[i + offset];        }    }    /**     * 连接另一个byte[],可设定来源数据的起始位置,以及长度,连接到目标数据的尾部     * @param b         byte[]  来源数据     * @param offset    int     来源数据起始位置     * @param length    int     来与数据长度     */    public void cat(byte[] b, int offset, int length) {        cat(mCap, b, offset, length);    }    /**     * 连接另一个byte[],可设定来源数据的起始位置到结尾,连接到目标数据的尾部     * @param b         byte[]  来源数据     * @param offset    int     来源数据起始位置     */    public void cat(byte[] b, int offset) {        cat(b, offset, b.length - offset);    }    /**     * 连接另一个byte[],来源数据全部连接到目标数据的尾部     * @param b byte[]  来源数据     */    public void cat(byte[] b) {        cat(b, 0);    }    /**     * 获得实际容器的byte[]数组     * @return  byte[]     */    public byte[] toBytes() {        return mBytes;    }    /**     * 输出对象全部属性     * @return  String     */    @Override    public String toString() {        return "Bytes{" +                "length=" + mCap +                ", data=" + Arrays.toString(mBytes) +                '}';    }    /**     * 输出16进制的数据,每个数据前可增加前缀header,数据之间可增加间隔space     * @param header    String  前缀     * @param space     String  间隔     * @return          String     */    public String toHexString(String header,String space){        StringBuffer buffer = new StringBuffer();        for(int i=0;i"%s%02x%s",header,mBytes[i],space));        }        return buffer.substring(0,buffer.length()-space.length());    }    /**     * 输出16进制的数据,数据之间可增加间隔space     * @param space     String  间隔     * @return          String     */    public String toHexString(String space){        return toHexString("",space);    }    /**     * 输出16进制的数据     * @return  String     */    public String toHexString(){        return toHexString("");    }}

应用示例:

@Test    public void addition_isCorrect() throws Exception {        Bytes bytes = new Bytes(new int[]{0x80,0x00});        int tt = bytes.readUInt16BE();        int mm = bytes.readInt16BE();        Bytes bb = new Bytes(new int[]{0x80, 0, 0, 128});        long ii = bb.readUInt16BE(2);        long nn = bb.readInt16BE(2);        bb.cat(bytes.toBytes());        int ll = bb.readUInt16BE(4);        System.out.print(Arrays.toString(bb.toBytes())+"\r\n");        System.out.print(bb.toString()+"\r\n");        System.out.print(bb.toHexString()+"\r\n");        System.out.print(bb.toHexString("0x"," ")+"\r\n");    }

输出

[-128, 0, 0, -128, -128, 0]Bytes{length=6, data=[-128, 0, 0, -128, -128, 0]}8000008080000x80 0x00 0x00 0x80 0x80 0x00

更多相关文章

  1. 范例解析:学习Android的IPC主板模式
  2. android的singleInstance启动模式及方法调用
  3. Android中遇到的简单工厂模式的几种实现
  4. android activity 四大启动模式及使用场景
  5. Android在MTP模式下,只显示指定文件夹
  6. Android——Activity四种启动模式
  7. 固定屏幕显示模式 ScreenOrientation
  8. 解决Android编辑框在全屏模式下无法检测布局变化的问题
  9. 转:Android下文件操作模式(含SDCard的读写)

随机推荐

  1. android 动态获取res资源id
  2. Android之MVP架构
  3. android之eclipse下查看android系统源代
  4. 【译】Android位图颜色模式的问题
  5. android媒体--stagefright概述【一】
  6. (三)Android(安卓)项目在Eclipse中的目录结
  7. 摩托罗拉公司在开发Android应用商店 – S
  8. Android应用程序通用自动脱壳方法研究
  9. UC/OS-II学习 2
  10. 【Android开发学习13】Android(安卓)Open