簡體   English   中英

從 java 中的字節數組編碼和解碼 object

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

我有一個字節數組:

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

和一個 class:

class abc{

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

}

在 python 中有一個 lib ctypes ,您可以在其中提供一個字節數組,並將其編碼為 class 的 object(絕對需要事先定義結構)。

我在 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.

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

我能想到的唯一解決方案是很多 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.

DataInputStream允許您從輸入 stream 中讀取原語。 請注意以下方法:

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

示例代碼:

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();
}

有幾種方法可以做到這一點。 這是一個簡單的:

byte[] values = [11, 10, 17, 05, 00, 0a, 01, 02]; //WARNING: update 0a to the right value 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};
    }

}

因此要創建一個新的 object(對象為小寫):

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

假設您已經查看了 Apache Commons 中的Serialization Utils ,您可以理解應該有某種基於 class 的 object 作為任何序列化算法的輸入。

但是,您希望避免使用單獨的專用 class 來存儲和檢索數據(如果我錯了,請澄清我)。 一種可能的解決方法是使用 java 中的內置 class 為您封裝數據。

例如,您可以將數據字段放入列表 ( ArrayList ) 甚至更好的 Map ( HashMap ) 中。 然后你可以序列化 map object 以便它可以傳遞。 好消息是這些類已經內置在 java 中,因此您不需要僅僅為了序列化而創建單獨的 class。

這是一個示例示例代碼:

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);
    }
}

正如您在此處看到的,我使用obj創建值,然后對其進行序列化,並newObj進行反序列化並分配回變量。

obj可能屬於一個 class,您可以序列化並通過網絡發送值,並且可以在另一個 object 上反序列化它們。 這是可能的,因為 HashMap 已經內置在 Java 中。

這里的好處是你不需要在兩個地方都有相同的 class 。 只要兩個類都具有上述變量(變量甚至不必具有相同的名稱,只要類型匹配,這將起作用),您就可以實現此解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM