Java 學習記錄87 — Object Input Output including Serialization — 6/7

張小雄
6 min readOct 19, 2021

--

承 86 — I/O Byte Streams

Location.java

package introduceIo;import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
public class Location implements Serializable {
private final int locationID;
private final String description;
private final Map<String, Integer> exits;
private final static long serialVersionUID = 1L; public Location(int locationID, String description, Map<String, Integer> exits) {
this.locationID = locationID;
this.description = description;
if (exits != null) {
this.exits = new LinkedHashMap<String, Integer>(exits);
} else {
this.exits = new LinkedHashMap<String, Integer>();
}
this.exits.put("Q", 0);
}
public int getLocationID() {
return locationID;
}
public String getDescription() {
return description;
}
public Map<String, Integer> getExits() {
return new LinkedHashMap<String, Integer>(exits);
}
protected void addExit(String direction, int location) {
exits.put(direction, location);
}
}

Locations.java

public static void main(String[] args) throws IOException {//        version 4
try (ObjectOutputStream locFile = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("src/introduceIo/locations.dat")))) {
for (Location location : locations.values()) {
locFile.writeObject(location);
}
}
}

static {
// read locations.dat
System.out.println("read locations.dat that combine location and direction in one file");
// version 2
try (ObjectInputStream locFile = new ObjectInputStream(new BufferedInputStream(new FileInputStream("src/introduceIo/locations.dat")))) {
boolean eof = false;
while (!eof) {
try {
Location location = (Location) locFile.readObject();
System.out.println("Read location " + location.getLocationID() + " : " + location.getDescription());
System.out.println("Found " + location.getExits().size() + " exits");
locations.put(location.getLocationID(), location);
} catch (EOFException e) {
eof = true;
System.out.println("EOF exception " + e.getMessage());
}
}
} catch (InvalidClassException e){
System.out.println("InvalidClassException " + e.getMessage());
} catch (IOException io) {
System.out.println("IO exception " + io.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException " + e.getMessage());
}
}

做了存讀的序列化

存儲的變得更簡單了

而且讀檔不需要分開讀兩個文件了

合併成一個檔案

如果輸出不順利的話

先把讀檔調回舊的方式,順利讀到後

用新的方式寫入,再用新的方式讀出

private final static long serialVersionUID = 1L;

加上這個可以確保,換到其他電腦也能照這個 UID 來做序列化操作

不加上這個,可能換台電腦時,結果會不同

如果先註銷的話

輸出結果:

InvalidClassException introduceIo.Location; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 351332483920865533

還有要序列化的內容,若是 object 都要是有序的

所以 HashMap 不行,LinkedHashMap 才可以

P.S 但序列化也有個明顯問題,但凡改動文件路徑,就會出錯上面錯誤,要先用舊方式重新寫入

本篇代碼

--

--

張小雄
張小雄

Written by 張小雄

記錄成為軟體工程師的過程

No responses yet