【发布时间】:2021-04-07 22:36:42
【问题描述】:
我正在尝试序列化 Java 对象,使其内容可以被现有的 reader.cc 模块读取,该模块当前读取用 C++ 生成的二进制文件。
以下是来自 reader.cc 的 sn-p,它读取 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、_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.cc、Java code。
【问题讨论】:
-
您是否尝试过使用十六进制编辑器以十六进制转储二进制文件的内容,并准确了解 Java 代码如何将数据写入其中,并将其与您的 C++ 代码所期望的进行比较阅读?如果你这样做了,你会在几秒钟内得到答案。
-
@RichardCritten 我愿意,但我不想修改 C++ 系统。
-
“它不起作用”信息不足。在不修改 C++ 的情况下,您至少可以调试它并查看它读取的值与您期望的值?
-
unit32_t是 32 位的。你写的是 64 位(long)。 -
@NicolaAmadio 看起来你现在搞乱了字节顺序 - 大端与小端。 (基本上写int的时候要反转字节数组的字节)
标签: java c++ serialization binary