有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c#如何使用Protocolbuffer在Java中反序列化文件?

希望在C#中创建一个序列化文件,然后在Java中反序列化该文件。为此,我使用协议缓冲库。以下是我所做的:

在C#中,我添加了protobuf net。dll和要序列化的类表示为:

人。cs

 [ProtoBuf.ProtoContract]
 public class Person
 {
    [ProtoBuf.ProtoMember(1)]
    public int Id {get;set;}
    [ProtoBuf.ProtoMember(2)]
    public string Name { get; set; }
 }

在main方法中,将其序列化如下:

 var person = new Person
    {
        Id = 12345,
        Name = "Fred",
    };
  using (var file = File.Create("somepath\\person.bin"))
    {
        Serializer.Serialize(file, person);
    }

我复制了这个bin文件,并将其放入ecilpse文件系统安卓/sdcard中,并试图对其进行反序列化

在eclipse-JAVA中,

添加protobuf。jar、外部库和创建人。包含以下内容的原型文件:

message Person{
required int32 Id=1;
required string Name=2;
}

有人能建议如何反序列化C#中创建的对象吗


共 (2) 个答案

  1. # 1 楼答案

    关于反序列化Java版本序列化的对象,Java文档说明了什么?基本上是:“那样做”。序列化的数据没有区别

    如果问题是Java示例以。proto文件,然后使用:

    string proto = Serializer.GetProto<Person>();
    

    尽管。你展示的原型看起来不错

  2. # 2 楼答案

    为在C#中创建的文件创建一个InputStream,并调用

    Person.parseFrom(InputStream)
    

    如果你想处理文件中的字节,这个方法还有其他重载

    如果要实现协议,则需要包含一个标头,以标识字节所代表的数据类型。从这里,您只需选择正确的proto来解析数据

    编辑

    我创建了一个类,用于将id映射到类,反之亦然,以帮助开发带有protobufs的协议。如果你没有开发一个网络传输协议,这可能没有帮助,但我敢肯定你是

    我知道你没有要求这个,但也许你会发现它很有用

    将ID注册到所有protobuff生成器中,然后在接收时检索正确的生成器以取消序列化字节。在发送之前,为每个protobuf对象获取正确的ID。ID将包含在每个数据包中,以便您知道每个数据包中的数据类型。(这里的数据包是抽象的,这也适用于流协议。)

    public class MessageTypeMap {
    private final Object lock;
    final HashMap<Integer, GeneratedMessageLite> messageParserMap;
    final HashMap<Class<?>, Integer> messageClassParserMap;
    
    public MessageTypeMap() {
        this.messageParserMap = new HashMap<Integer, GeneratedMessageLite>();
        this.messageClassParserMap = new HashMap<Class<?>, Integer>();
        this.lock = new Object();
    }
    
    public void addMessageType(int typeID, GeneratedMessageLite message) {
        synchronized (this.lock) {
            this.messageParserMap.put(typeID, message);
            this.messageClassParserMap.put(message.getDefaultInstanceForType()
                    .getClass(), typeID);
        }
    }
    
    public GeneratedMessageLite getBuilderFor(int id) throws ProtocolException {
        synchronized (this.lock) {
            if (this.messageParserMap.containsKey(id)) {
                GeneratedMessageLite lite = this.messageParserMap.get(id);
                return lite;
            } else {
                throw new ProtocolException("No message builder for ID " + id);
            }
        }
    }
    
    public int getIDFor(Object obj) throws ProtocolException {
        synchronized (this.lock) {
            if (obj == null) {
                throw new NullPointerException(
                        "Object null while retrieving type id.");
            }
            Class<?> c = obj.getClass();
            if (this.messageClassParserMap.containsKey(c)) {
                int typeID = this.messageClassParserMap.get(c);
                return typeID;
            } else {
                throw new ProtocolException("No type id for class "
                        + c.getSimpleName());
            }
        }
    }
    

    }

    用法:

    MessageTypeMap map = new MessageTypeMap();
    //register the person type.
    map.addMessageType(100, Person.getDefaultInstance());
    //use this to unserialize whatever object some bytes are.
    GeneratedMessageLite builder = mpa.getBuilderFor(100);
    //be sure to include the type id with each transmission of an object.
    int id = map.getIDFor(Person.getDefaultInstance());