2014-03-13 72 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

相關問題