在java中序列化并在c中读取++

kq4fsx7k  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(357)

我正在尝试序列化一个java对象,使其内容可以由现有的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中所做的,我正在序列化的3个变量(以及从myobject读取的变量)是 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、\u z9test\u looppii、4294967295;这些是我正在序列化的值:15,\uz9test\ulooppii,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.cc、java代码。

wtlkbnrh

wtlkbnrh1#

关键是正确序列化int/long。
我选择使用 int 因为它有32个字节,和 uint32_t 在读卡器端。这就足够把它的字节数取出来并反转(因为big-endian和little-endian,谢谢johannes kuhn的建议)。
方法如下:

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

我用Guava从整数中提取字节( Ints.toByteArray ),但也有其他方法可以做到这一点,如在问题中注解掉的方法(除此之外,只需反转字节数组)。

相关问题