繁体   English   中英

如何在Java类对象中映射二进制数据?

[英]How to map binary data in java class object?

输入数据:十六进制64字节

String binaryData="01000076183003104000800180f5010100010100000063000000630000006300000063000000000000000000820000000200b8010307010700640005e1cbe180";

问题是读取此二进制数据并设置在类对象中,这是模型

public class Transaction_PLUSale {


    public byte opcode;
    public byte[] code=new byte[7];

    public  byte flag1;
    public  byte flag2;
    public byte flag3;
    public byte flag4;
    public byte flag5;
    public short deptnum;
    public byte multi_sell_unit;
    public byte return_type;
    public byte tax_pointer;
    public int qty;
    public int price;
    public int amount;
    public int no_tax_price;
    public int no_tax_amount;
    public int return_surcharge_percent;
    public byte product_code;
    public byte flags;
    public TransactionTail tail;
}

我目前正在以这种方式在每个字段中设置值。

String hexArray[]=  binaryData.split("(?<=\\G..)");
public static void readPLUSalesData(String hexArray[]) {
        Transaction_PLUSale pluSale=new Transaction_PLUSale();
        pluSale.setOpcode(Byte.valueOf(hexArray[0]));

        byte arr[]=new byte[7];
        for(int i=1;i<=7;i++) {
            arr[i-1]=Byte.valueOf(hexArray[i]);
        }
        pluSale.setCode(arr);
        pluSale.setFlag1(Byte.valueOf(hexArray[8]));
        pluSale.setFlag2(Byte.valueOf(hexArray[9]));
        pluSale.setFlag3(Byte.valueOf(hexArray[10]));
        pluSale.setFlag4(Byte.valueOf(hexArray[11]));
        pluSale.setFlag5(Byte.valueOf(hexArray[12]));
        pluSale.setDeptnum((short)Integer.parseInt((hexArray[14]+hexArray[13]),16));
        pluSale.setMulti_sell_unit(Byte.valueOf(hexArray[15]));
        pluSale.setReturn_type(Byte.valueOf(hexArray[16]));;
        pluSale.setTax_pointer(Byte.valueOf(hexArray[17]));
        pluSale.setQty(Integer.parseInt((hexArray[21]+hexArray[20]+hexArray[19]+hexArray[18]),16));
        pluSale.setPrice(Integer.parseInt((hexArray[25]+hexArray[24]+hexArray[23]+hexArray[22]),16));
        pluSale.setAmount(Integer.parseInt((hexArray[29]+hexArray[28]+hexArray[27]+hexArray[26]),16));
        pluSale.setNo_tax_price(Integer.parseInt((hexArray[33]+hexArray[32]+hexArray[31]+hexArray[30]),16));
        pluSale.setNo_tax_amount(Integer.parseInt((hexArray[37]+hexArray[36]+hexArray[35]+hexArray[34]),16));
        pluSale.setReturn_surcharge_percent(Integer.parseInt((hexArray[41]+hexArray[40]+hexArray[39]+hexArray[38]),16));
        pluSale.setProduct_code(Byte.valueOf(hexArray[42]));
        pluSale.setFlags(Byte.valueOf(hexArray[43]));

}

一切正常。 但我希望它是通用的。 因此,而不是逐字节给出值。 我想直接将其映射到类字段。

在.net中,我们正在对所需的相同功能进行编组。 这是例子

foreach (KeyValuePair<string, byte[]> s in t)
                    {
//byte array consist of bytes of the above hexadecimal string.
                        Ticket ticket = new Ticket();

                        int count = Marshal.SizeOf(typeof(Transaction_Coupon));
                        MemoryStream ms = new MemoryStream(s.Value);
                        byte[] readBuffer = new byte[count];
                        BinaryReader br = new BinaryReader(ms);
                        readBuffer = br.ReadBytes(count);
                        GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);

//here we are mapping byte data to each field
                        Transaction_PLUSale t_plusale = (Transaction_PLUSale)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Transaction_PLUSale));

}

要将byte[]二进制数据转换为具有字段的类,没有内存模板可将数据移入。一个好的解决方案是在字节数组或InputStream上使用ByteBuffer

public static void readPLUSalesData(String[] hexArray) {
    byte[] bytes = new byte[hexArray.length];
    for (int i = 0; i < bytes.length; ++i) {
         bytes[i] = Byte.parseByte(hexArray[i], 16);
    }

    ByteBuffer buf = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN;

    Transaction_PLUSale pluSale=new Transaction_PLUSale();
    pluSale.setOpcode(buf.get());

    byte[] arr[] = new byte[7];
    buf.get(arr);
    pluSale.setCode(arr);
    pluSale.setFlag1(buf.get());
    pluSale.setFlag2(buf.get());
    pluSale.setFlag3(buf.get());
    pluSale.setFlag4(buf.get());
    pluSale.setFlag5(buf.get());
    pluSale.setDeptnum(buf.getShort());
    pluSale.setMulti_sell_unit(buf.get());
    pluSale.setReturn_type(buf.get());
    pluSale.setTax_pointer(buf.get());
    pluSale.setQty(buf.getInt());
    pluSale.setPrice(buf.getInt());
    pluSale.setAmount(buf.getInt());
    pluSale.setNo_tax_price(buf.getInt());
    pluSale.setNo_tax_amount(buf.getInt());
    pluSale.setReturn_surcharge_percent(buf.getInt());
    pluSale.setProduct_code(buf.get());
    pluSale.setFlags(buf.get());
}

还有其他解决方案,例如使用反射,效率很低。

我在这里使用了小端字节顺序,java中的默认值是大端字节。

有ObjectOutputStream,Serializable,使用序列化的持久性。 它还存储类数据,因此不是您想要的语言不可知格式。

使用ByteBuffer进行开发时,检查读取位置很有意义。

如果您对XML持久性感兴趣,那么带有批注的JAXB提供了一种基于反射的不错的方式,而无需处理每个字段。

备注: Type[] variable是首选表示法; 最初将Type var[]添加到java中以与C / C ++兼容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM