到目前为止,我一直在使用Protocol Buffers来使用代码生成的类来序列化和反序列化对象。
现在我正在尝试序列化和反序列化单个64位整数。问题是,我在Java和C#中得到了不同的结果。
以下是我在Java中的表现....
private static byte[] convertLongToByteArray(long value) throws IOException {
int size = CodedOutputStream.computeInt64SizeNoTag(value);
byte[] buffer = new byte[size];
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(buffer);
codedOutputStream.writeInt64NoTag(value);
codedOutputStream.flush();
codedOutputStream.checkNoSpaceLeft();
return buffer;
}
以下是我在C#中使用protobuf.net的方式:
public void SerializeLongValue()
{
long n = 9876;
byte[] memoryBuffer = null;
using (MemoryStream destination = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(destination, n);
destination.Flush();
memoryBuffer = destination.ToArray();
}
using (MemoryStream source = new MemoryStream(memoryBuffer))
{
long result = ProtoBuf.Serializer.Deserialize<long>(source);
Assert.AreEqual(n, result);
}
}
java代码将数字9876
转换为[0x94, 0x4D]
C#代码将数字9876
转换为[0x08, 0x94, 0x4D]
如何执行此操作以使com.google.protobuf
和protobuf.net
生成相同的输出?
答案 0 :(得分:2)
protobuf.net方法ProtoBuf.Serializer.Serialize
强制将字段标题(字段编号= 1)放入流中。这是您执行序列化的唯一方法;此方法调用许多不公开的内部方法。
我正在使用的解决方案是将Java代码更改为包含字段标题。
这是我的新Java代码。
private static byte[] convertLongToByteArray(long value) throws IOException {
int size = CodedOutputStream.computeTagSize(1) + CodedOutputStream.computeInt64SizeNoTag(value);
byte[] buffer = new byte[size];
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(buffer);
codedOutputStream.writeInt64(1, value);
codedOutputStream.flush();
codedOutputStream.checkNoSpaceLeft();
return buffer;
}
public static long convertByteArrayToLong(byte[] byteArray) throws IOException {
CodedInputStream codedInputStream = CodedInputStream.newInstance(byteArray);
codedInputStream.readTag();
return codedInputStream.readInt64();
}
我所做的改变是:
CodedOutputStream.WriteInt64NoTag
,请致电CodedOutputStream.WriteInt64
CodedOutputStream.ReadTag
CodedOutputStream.ReadInt64