簡體   English   中英

在 Java 中序列化並在 C++ 中讀取

[英]Serialize in Java and read in C++

我正在嘗試序列化 Java object,使其內容可以被現有的reader.cc模塊讀取,該模塊當前讀取在 C++ 中生成的二進制文件。

以下是reader.cc的片段,其中讀取 3 個變量( name_len, fname, and feature_names_count ):

uint32_t name_len;
in.read((char *)&name_len, sizeof(uint32_t));          

char *fname = new char[name_len + 1];
in.read(fname, sizeof(char) * name_len);           
fname[name_len] = '\0';

uint32_t feature_names_count;
in.read((char *)&feature_names_count, sizeof(uint32_t));  

這就是我在 Java 中所做的事情,其中我正在序列化(並從myObject讀取)的 3 個變量是int, String, int類型(我嘗試了每種注釋方法):

    private static void createBinaryFile(TestClassToSerialize myObject) throws IOException {
        File myFile = new File(PATHNAME);
        myFile.createNewFile();
        writeObjectToFile(new FileOutputStream(myFile), myObject);
    }

    private static void writeObjectToFile(FileOutputStream fos, TestClassToSerialize myObject) throws IOException {
        fos.write(intToByteArray(myObject.getNameLen()));
        fos.write(myObject.getFname().getBytes());
        fos.write(intToByteArray(myObject.getFeatureNamesCount()));
        fos.close();
    }

    public static byte[] intToByteArray(int data) {
        return Ints.toByteArray(data);
    }
//    public static final byte[] intToByteArray(int value) {
//        return new byte[] {
//                (byte)(value >>> 24),
//                (byte)(value >>> 16),
//                (byte)(value >>> 8),
//                (byte)value};
//    }

//    public static byte[] intToByteArray(int data) {
//        byte[] result = new byte[4];
//        result[0] = (byte) ((data & 0xFF000000) >> 24);
//        result[1] = (byte) ((data & 0x00FF0000) >> 16);
//        result[2] = (byte) ((data & 0x0000FF00) >> 8);
//        result[3] = (byte) ((data & 0x000000FF) >> 0);
//        return result;
//    }

這些是從reader.cc讀取的值: 251658240, _Z9test_loopPii, 4294967295 這些是我要序列化的值: 15, _Z9test_loopPii, 4

我還嘗試將數字存儲為long ,然后使用以下方法將其序列化為字節:

public static byte[] longToBytes(long x) {
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
        buffer.putLong(x);
        return Arrays.copyOfRange(buffer.array(), 0, 4);
    }

但是,當我在 C++ 中反序列化時,我得到的值與從其他代碼(序列化整數的代碼)中得到的值相同。

我無法更改 C++ 代碼,但我可以在 Java 中做任何我想做的事情,甚至可以在myObject中以不同格式存儲數據。

你有什么建議嗎?

以下是包含上述代碼的存儲庫的鏈接(它們都是 OSS),以防某些上下文可能有所幫助: reader.ccJava 代碼

關鍵是正確序列化 int/long。

我選擇使用int是因為它有 32 個字節,與閱讀器端的uint32_t相同。 獲取其中的字節並將其反轉就足夠了(因為大端與小端,感謝 Johannes Kuhn 的建議)。

這是方法:

public static byte[] intToByteArray(int data) {
        byte[] bytes = Ints.toByteArray(data);
        ArrayUtils.reverse(bytes);
        return bytes;
    }

我使用 Guava 從 integer ( Ints.toByteArray ) 中獲取字節,但也有其他方法可以做到這一點,比如問題中注釋掉的那些(除此之外,只需反轉字節數組)。

暫無
暫無

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

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