简体   繁体   English

无法读取用C ++序列化的Java数据

[英]Cannot read in Java data serialized in C++

I have a Java client connected via socket to a C++ server. 我有一个Java客户端通过套接字连接到C ++服务器。

The C++ server sends back to the client serialized objects. C ++服务器将回送给客户端序列化对象。

However serialization works differently for Java and C++, so I cannot read the objects in that way: 但是,序列化对Java和C ++的工作方式不同,所以我无法以这种方式读取对象:

objectInputStream.readObject();

This forces me to read each single value of the object manually: 这迫使我手动读取对象的每个单独值:

byte[] buffer = read(FOUR_BYTES);
int flag = convertBufferToInt(buffer);

byte[] buffer = read(FOUR_BYTES);
float price = convertBufferToFloat(buffer);

// More stuff

myObject.setFlag(flag);
myObject.setPrice(price);

// More stuff

That's very hard to maintain. 这很难维护。 Isn't there an easier way to fill in my object with data? 是不是有更简单的方法用数据填充我的对象?

Yes there is (are). 是的,有(是)。 You have 2 options using only the standard library: 只有标准库有2个选项:

Using the DataInputStream class 使用DataInputStream

Check out the DataInputStream class. 查看DataInputStream类。 It has methods to read values of primitive types like readByte() , readInt() , readLong() , readFloat() , readChar() , readUTF() (for reading UTF-8 encoded String ) etc. 它有读取原始类型值的方法,如readByte()readInt()readLong()readFloat()readChar()readUTF() (用于读取UTF-8编码的String )等。

So your code becomes as simple as: 所以你的代码变得如此简单:

// Obtain InputStream from Socket:
InputStream is = ...;
// Create DataInputStream:
DataInputStream dis = new DataInputStream(is);

myObject.setFlag(dis.readInt());
myObject.setPrice(dis.readFloat());

Using the ByteBuffer class 使用ByteBuffer

For this you have to read first the whole data into a byte array. 为此,您必须首先将整个数据读入字节数组。 Once you've done that, you can create a ByteBuffer using the ByteBuffer.wrap(byte[] array) method. 完成后,可以使用ByteBuffer.wrap(byte[] array)方法创建ByteBuffer The ByteBuffer class also supports reading primitive types just like the DataInputStream class. ByteBuffer类也支持读取原始类型,就像DataInputStream类一样。

The good thing about ByteBuffer that it supports changing the byte order (the order how the low and high bytes of a multi-byte value like int are read/written): ByteBuffer.order(ByteOrder bo) . ByteBuffer的优点是它支持更改字节顺序 (读取/写入多字节值如int的低字节和高字节的顺序): ByteBuffer.order(ByteOrder bo) This is very useful if you're communicating with systems which use a differnet byte order (which might apply in your case). 如果您与使用不同字节顺序的系统进行通信(在您的情况下可能适用),这非常有用。

Example using ByteBuffer : 使用ByteBuffer示例:

// Read all your input data:
byte[] data = ...;
// Create ByteBuffer:
ByteBuffer bb = ByteBuffer.wrap(data);

myObject.setFlag(bb.getInt());
myObject.setPrice(bb.getFloat());

To solve this in general you would need to write a C++ parser for objects serialized in Java. 要解决这个问题,您需要为使用Java序列化的对象编写C ++解析器。 This is no small task. 这不是一项小任务。

Rather, I would recommend that you find some serialization format that is easy to parse and share between your Java and C++ programs. 相反,我建议您找到一些易于在Java和C ++程序之间解析和共享的序列化格式。 Preferably a format where there exists Java as well as C++ libraries for the serialization/deserialization. 优选地,存在用于序列化/反序列化的Java以及C ++库的格式。 JSON or Google Protocol Buffers are obvious candidates. JSON或Google Protocol Buffers是明显的候选者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM