2014-03-13 121 views
1

下面是一个示例代码,其中ListStringMap已被序列化和反序列化。可以说我需要通过电汇发送file。接收方客户如何知道反序列化按照List,String,Map的顺序?他应该怎么知道要读取的对象是什么?如何在不知道序列化内容的情况下读取ObjectInputStream?

public static void serializeBunchOfObjects() throws FileNotFoundException, IOException { 
    List<String> foo = new ArrayList<String>(); 
    String str = "foo"; 
    Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo")); 
    oos.writeObject(foo); 
    oos.writeObject(str); 
    oos.writeObject(map); 

    oos.close(); 
} 

public static void deserializeBunchOfObjects() throws FileNotFoundException, IOException, ClassNotFoundException { 
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("foo")); 
    List<String> foo = (List)ois.readObject(); 
    String str = (String) ois.readObject(); 
    Map<Integer, Integer> mapper = (Map) ois.readObject(); 
} 
+0

“?应该知道,反序列化接收客户端如何在列表中,字符串,地图的顺序”问题就没有意义了。客户如何知道它是一个对象流?客户端如何知道对象正在被发送* *任何客户端 - 服务器系统都有一个应用协议,并且两端都应该实现它。 – EJP

回答

2

我想提出一个单独的解决方案(或者至少变化)来@Lynch。

当您向客户端发送消息时,是否有一组定义的消息类型?如果你这样做,你可以在消息主体周围定义包装对象,它可以用作一种头部。

你可以定义一个FooMessage其中有作为成员要连载中的字段:

public class FooMessage 
{ 
    private static final long serialVersionUID = 1L; 

    private final List<String> theList; 
    private final String string; 
    private final Map<String, Object> theMap; 
} 

然后,而不是单独连载部分,序列化的包装”

final FooMessage msg = new FooMessage(...); 

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo")); 
oos.writeObject(msg); 

这样,至少你有一个简单的方法来定义将被序列化的各个字段,包装的额外空间和时间开销将非常小。现在,你仍然可以使用@写String来表示消息类型第林奇的建议...

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo")); 
oos.writeUTF("FooMessage"); 
oos.writeObject(msg); 

...或者,如果消息的数量是相当小的,你可以逃脱不串并简单地测试对象类型:

final Object received = ois.readObject(); 
if (received instanceof FooMessage) 
{ 
    ... 
} 
else if (received instanceof BarMessage) 
{ 
} 

最后一个变化是,你可以从一个超类,其中包含表示枚举类型继承你的具体消息类型:

public abstract class MessageWrapper 
{ 
    public MessageWrapper(YourMessageType type) 
    { 
    this.type = type; 
    } 

    public abstract YourMessageType getType(); 
} 

public class FooMessage extends MessageWrapper 
{ 
    public FooMessage() 
    { 
    super(YourMessageType.FOO); 
    } 
} 

这允许你做:

final MessageWrapper received = (MessageWrapper) ois.readObject(); 
switch (received.getType()) 
{ 
    case FOO: 
    return handleFoo((FooMessage) received); 
    case BAR: 
    return handleBar((BarMessage) received); 
} 
1

您应该首先序列化一个标题,告诉您文件其余部分的内容是什么。这样,您反序列化的第一件事就是标题(换句话说就是文件结构的表示)。

编辑

首先你要知道哪些类型将连载的对象,那么你可以创建一个头的分析器。

我不能提供一个完整的示例,但我可以帮助您构建标题。如果你操作的字符串,字符串地图列表的-,那么你的头看起来是这样的:

List<String> header = new List<String>(); 
header.add("list-of-string"); 
header.add("string"); 
header.add("map"); 
+0

任何代码片段,以帮助我呢? – JavaDeveloper

+0

不必要的。 instanceof操作符会告诉你每个对象实际是什么。 – EJP

相关问题