gpt4 book ai didi

java - 如何在不知道序列化内容的情况下读取 ObjectInputStream?

转载 作者:行者123 更新时间:2023-11-29 05:26:56 24 4
gpt4 key购买 nike

下面是一个示例代码,其中对 ListStringMap 进行了序列化和反序列化。假设我需要通过网络发送 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();
}

最佳答案

我想向@Lynch 提出一个单独的解决方案(或至少是一个变体)。

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

您可以定义一个 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);

这样,至少您可以轻松地定义将被序列化的各个字段。包装器的额外空间和时间开销将非常小。

现在,您仍然可以采用@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)
{
}

最后一个变体是您可以从父类(super class)继承您的具体消息类型,父类(super class)包含以枚举表示的类型:

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);
}

关于java - 如何在不知道序列化内容的情况下读取 ObjectInputStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22367370/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com