我希望这篇文章可以帮助同一场景中的其他人。 我一直在尝试使用协议缓冲区来保存和读取普通对象到二进制文件,并且与平台/语言无关。
在一个平台中序列化/反序列化时一切正常,但如果我尝试从java平台读取.net中创建的二进制文件,反之亦然。
在C#中我有以下poco:
[ProtoContract]
public class PocoDto
{
[ProtoMember(1)]
public string name { get; set; }
[ProtoMember(2)]
public int timestamp { get; set; }
}
在java中,pojo是:
import io.protostuff.Tag;
public final class PocoDto {
@Tag(1)
public String name;
@Tag(2)
public int timestamp;
}
使用protobuf-net在.net中序列化的方法是:
internal static void AppendToBin(PocoDto poco, string path)
{
using (var fs = new FileStream(path, FileMode.Append))
{
Serializer.SerializeWithLengthPrefix(fs, poco, PrefixStyle.Base128, 1);
}
}
虽然我用来反序列化的方法是
public static List<PocoDto> FromBin(this string path)
{
using (var fs = new FileStream(path, FileMode.Open))
{
return Serializer.DeserializeItems<T>(fs, PrefixStyle.Base128, 1).ToList();
}
}
使用protostuff在java中序列化的方法是:
public static void append(PocoDto pojo, String filePath) throws IOException
{
Schema<PocoDto> schema = RuntimeSchema.getSchema(PocoDto.Class);
File file = new File(filePath);
file.createNewFile();
FileOutputStream out = new FileOutputStream(file, true);
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
ProtostuffIOUtil.writeDelimitedTo(out, pojo, schema, buffer);
buffer.clear();
out.flush();
out.close();
}
用于反序列化:
public static List<PocoDto> fromBin(String filePath) throws IOException
{
Schema<PocoDto> schema = RuntimeSchema.getSchema(pojoType);
File file = new File(filePath);
if(!file.exists())
{
return null;
}
FileInputStream inStream = new FileInputStream(new File(filePath));
return ProtobufIOUtil.parseListFrom(inStream, schema);
}
通过比较在每种情况下创建的两个二进制文件,似乎C#中的一个总是在每个条目后附加一个换行符,而在java中生成的文件不会发生这种情况。 此外,使用protostuff创建列表会添加不同的分隔符,并且它似乎不会以相同的方式处理长度前缀。 我只是想知道在设置缓冲区时是否选择了错误的选项,或者两个输出是否真的不兼容。 谢谢你的帮助