简体   繁体   English

从 java 中的字节数组编码和解码 object

[英]encoding and decoding object from byte array in java

I have a byte array:我有一个字节数组:

[11, 10, 17, 05, 00, 0a, 01, 02] [11、10、17、05、00、0a、01、02]

and a class:和一个 class:

class abc{

    short var1;              // [11, 10]
    int var2;                // [17, 05, 00, 0a]
    byte var3;               // [01]
    byte var4;               // [02]

}

In python there is a lib ctypes where you can provide a byte array and it will encode it to a object of a class (definitely structure needs to be defined before hand).在 python 中有一个 lib ctypes ,您可以在其中提供一个字节数组,并将其编码为 class 的 object(绝对需要事先定义结构)。

I am looking something similar in java, basically what I am looking for a method which can encode and decode byte array.我在 java 中寻找类似的东西,基本上我正在寻找一种可以编码和解码字节数组的方法。

[11, 10, 17, 05, 00, 0a, 01, 02] => (some method) => object abc: abc.getVar3() // value of var3 needs to be 1 as per above structure.

also object abc => (some method) => [11, 10, 17, 05, 00, 0a, 01, 02] .还有object abc => (some method) => [11, 10, 17, 05, 00, 0a, 01, 02]

Only solution I can think of is lots of if else statement is there any better way to do it.我能想到的唯一解决方案是很多 if else 语句是否有更好的方法来做到这一点。

I have checked this answer it serialises entire class as byte object but I only want to encode data, basically inject data in object and also retrieve data from object in byte array. I have checked this answer it serialises entire class as byte object but I only want to encode data, basically inject data in object and also retrieve data from object in byte array.

DataInputStream allows you to read primitives from an input stream. DataInputStream允许您从输入 stream 中读取原语。 Look out for following methods:请注意以下方法:

  • readShort()
  • readInt()
  • readByte()

Example code:示例代码:

byte[] data = {0x11, 0x10, 0x17, 0x05, 0x00, 0x0a, 0x01, 0x02};

try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(data))) {
    abc value = new abc();
    value.var1 = in.readShort();
    value.var2 = in.readInt();
    value.var3 = in.readByte();
    value.var4 = in.readByte();
}

There's several ways to do that.有几种方法可以做到这一点。 Here's a simple one:这是一个简单的:

byte[] values = [11, 10, 17, 05, 00, 0a, 01, 02]; //WARNING: update 0a to the right value in java

The class definition (class name start with uppercase in java): class 定义(类名在java中以大写开头):

class Abc{

    short[] var1;              // [11, 10]
    int[] var2;                // [17, 05, 00, 0a]
    byte var3;               // [01]
    byte var4;               // [02]
    
    public Abc(byte[] values){
      var1 = new short[]{(short)values[0],(short)values[1]};
      var2 = new int[]{(int)values[2],(int)values[3],(int)values[4],(int)values[5]};
      var3 = values[6];
      var4 = values[7];

    }
    
    public byte[] getBytes(){
      return new byte[]{ (byte)var1[0], (byte)var1[1], (byte)var2[0],(byte)var2[1], (byte)var2[2], (byte)var2[3], var3, var4};
    }

}

So to create a new object (objects are lowercase):因此要创建一个新的 object(对象为小写):

Abc abc = new Abc(values);
byte[] result = abc.getBytes();

Assuming you have looked at Serialization Utils from Apache Commons, you could understand that there should be some sort of class based object to be an input for any serialization algorithm.假设您已经查看了 Apache Commons 中的Serialization Utils ,您可以理解应该有某种基于 class 的 object 作为任何序列化算法的输入。

However you want to avoid having a separate dedicated class to store and retrieve data (if I'm wrong clarify me).但是,您希望避免使用单独的专用 class 来存储和检索数据(如果我错了,请澄清我)。 One possible workaround is to use a built-in class in java to encapsulate the data for you.一种可能的解决方法是使用 java 中的内置 class 为您封装数据。

For example you could put your data fields in a List ( ArrayList ) or even better a Map ( HashMap ).例如,您可以将数据字段放入列表 ( ArrayList ) 甚至更好的 Map ( HashMap ) 中。 Then you could serialize the map object so that it can be passed around.然后你可以序列化 map object 以便它可以传递。 The good thing is these classes are already built into java so you don't need to create a separate class just for the sake of serialization.好消息是这些类已经内置在 java 中,因此您不需要仅仅为了序列化而创建单独的 class。

Here is a sample example code:这是一个示例示例代码:

import org.apache.commons.lang3.SerializationUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

class Abc {

    short var1;              // [11, 10]
    int var2;                // [17, 05, 00, 0a]
    byte var3;               // [01]
    byte var4;               // [02]

    public Map<String, Object> toMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("var1", var1);
        map.put("var2", var2);
        map.put("var3", var3);
        map.put("var4", var4);

        return map;
    }

    public byte[] serializeMap() {
        return SerializationUtils.serialize((Serializable) toMap());
    }

    public Map<String, Object> deSerializeMap(byte[] serializedObject) {
        return SerializationUtils.deserialize(serializedObject);
    }

    public void setParams(Map<String, Object> deSerializedObject) {
        this.var1 = (short) deSerializedObject.get("var1");
        this.var2 = (int) deSerializedObject.get("var2");
        this.var3 = (byte) deSerializedObject.get("var3");
        this.var4 = (byte) deSerializedObject.get("var4");
    }
}

public class Test2 {
    public static void main(String[] args) {

        Abc obj = new Abc();
        obj.var1 = 10000;
        obj.var2 = 500000;
        obj.var3 = 2;
        obj.var4 = 30;

        Abc newObj = new Abc();
        newObj.setParams(newObj.deSerializeMap(obj.serializeMap()));

        System.out.printf("var1: %s\nvar2: %s\nvar3: %s\nvar4: %s\n", newObj.var1, newObj.var2, newObj.var3, newObj.var4);
    }
}

As you can see here, I use obj to create the values, then serialize it and newObj to deserialize and assign back to the variable.正如您在此处看到的,我使用obj创建值,然后对其进行序列化,并newObj进行反序列化并分配回变量。

obj could be belong to one class and you could serialize and send the values through network and can deserialize them on another object. obj可能属于一个 class,您可以序列化并通过网络发送值,并且可以在另一个 object 上反序列化它们。 This is possible because the HashMap is already built into Java.这是可能的,因为 HashMap 已经内置在 Java 中。

Good thing here is that you don't need to have same class in both places.这里的好处是你不需要在两个地方都有相同的 class 。 As long as both classes have above variables (variables don't even have to have a same name either, as long as type matches, this will work), you could implement this solution.只要两个类都具有上述变量(变量甚至不必具有相同的名称,只要类型匹配,这将起作用),您就可以实现此解决方案。

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

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