我正在尝试序列化一个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代码。
1条答案
按热度按时间wtlkbnrh1#
关键是正确序列化int/long。
我选择使用
int
因为它有32个字节,和uint32_t
在读卡器端。这就足够把它的字节数取出来并反转(因为big-endian和little-endian,谢谢johannes kuhn的建议)。方法如下:
我用Guava从整数中提取字节(
Ints.toByteArray
),但也有其他方法可以做到这一点,如在问题中注解掉的方法(除此之外,只需反转字节数组)。