以下是序列化和反序列化List
,String
和Map
的示例代码。假设我需要通过电汇发送file
。接收客户端如何知道反序列化是按List,String,Map的顺序排列的?他怎么知道要把被读物体投射到什么地方?
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 :(得分: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;
}
然后,不是单独序列化部件,而是序列化包装器&#34;
final FooMessage msg = new FooMessage(...);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo"));
oos.writeObject(msg);
这样,至少你有一种简单的方法来定义将被序列化的各个字段。包装器的额外空间和时间开销将非常小。
现在,您仍然可以使用@Lynch建议编写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 :(得分:1)
您应首先序列化标题,告诉您文件其余部分的内容。这样,您反序列化的第一件事是标题(换句话说是文件结构的表示)。
修改强>
首先,你必须知道要序列化的对象类型,然后你可以为标题创建一个解析器。
我无法提供完整的示例,但我可以帮助您构建标题。如果你操纵string,string-of-string和map,那么你的标题可能如下所示:
List<String> header = new List<String>();
header.add("list-of-string");
header.add("string");
header.add("map");