承 85 — Load Big Location and Exits Files
Locations.java
public static void main(String[] args) throws IOException { // version 3
try (DataOutputStream locFile = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("src/introduceIo/locations.dat")))) {
for (Location location : locations.values()) {
locFile.writeInt(location.getLocationID());
locFile.writeUTF(location.getDescription());
System.out.println("Writing location " + location.getLocationID() + " : " + location.getDescription());
;
System.out.println("Writing " + (location.getExits().size() - 1) + " exits.");
locFile.writeInt(location.getExits().size() - 1);
for (String direction : location.getExits().keySet()) {
if (!direction.equalsIgnoreCase("Q")) {
System.out.println("\t\t" + direction + "," + location.getExits().get(direction));
locFile.writeUTF(direction);
locFile.writeInt(location.getExits().get(direction));
}
}
}
}
}
又換了一個輸出方式,這個輸出的結果,是電腦看的格式(binary data)
A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in.
運行完會產生 locations.dat
點進去看,會發現部份是亂碼,這是正常的,因為沒轉碼成我們看得懂的
Locations.java
static {
// version 5
try (DataInputStream locFile = new DataInputStream(new BufferedInputStream(new FileInputStream("locations.dat")))) {
while (true) {
Map<String, Integer> exits = new LinkedHashMap<>();
int locID = locFile.readInt();
String description = locFile.readUTF();
int numExits = locFile.readInt();
System.out.println("Read location " + locID + " : " + description);
System.out.println("Found " + numExits + " exits");
for (int i = 0; i < numExits; i++) {
String direction = locFile.readUTF();
int destination = locFile.readInt();
exits.put(direction, destination);
System.out.println("\t\t" + direction + "," + destination);
}
locations.put(locID, new Location(locID, description, exits));
}
} catch (IOException io) {
System.out.println("IOException!");
} }
接著就是讀取,怎麼寫入就怎麼讀出
寫好去 Main 測試是否正常
但這樣寫 while
跟 catch
會有個問題
原本用意是當 stream 裡的資料跑完,會打印提示
輸出結果:
Read location 140 : DEAD END
Found 1 exits
N,112
IOException!
YOU ARE STANDING AT THE END OF A ROAD BEFORE A SMALL BRICK BUILDING. AROUND YOU IS A FOREST. A SMALL STREAM FLOWS OUT OF THE BUILDING AND DOWN A GULLY.
Available exits are W, U, E, S, D, N, Q,
但遇到其他狀況也會打印同樣錯誤,這樣要除錯就不知道是哪發生問題
例如:
try (DataInputStream locFile = new DataInputStream(new BufferedInputStream(new FileInputStream("locations%^$^#^.dat"))))
像改檔案名,讓系統讀不到檔案,也是報同一個錯誤
輸出結果:
IOException!
Exception in thread “main” java.lang.NullPointerException
at introduceIo.Main.main(Main.java:31)
try (DataInputStream locFile = new DataInputStream(new BufferedInputStream(new FileInputStream("locations.dat")))) {
boolean eof = false;
while (!eof) {
try {
Map<String, Integer> exits = new LinkedHashMap<>();
int locID = locFile.readInt();
String description = locFile.readUTF();
int numExits = locFile.readInt();
System.out.println("Read location " + locID + " : " + description);
System.out.println("Found " + numExits + " exits");
for (int i = 0; i < numExits; i++) {
String direction = locFile.readUTF();
int destination = locFile.readInt();
exits.put(direction, destination);
System.out.println("\t\t" + direction + "," + destination);
}
locations.put(locID, new Location(locID, description, exits));
} catch (EOFException e) {
System.out.println("no data in stream !");
eof = true;
}
}
} catch (IOException io) {
System.out.println("IOException!");
}
多加一層 try catch 和加入一個條件做判斷,即可解決
檔案名改回來正常
輸出結果:
Found 1 exits
N,112
no data in stream !
YOU ARE STANDING AT THE END OF A ROAD BEFORE A SMALL BRICK BUILDING. AROUND YOU IS A FOREST. A SMALL STREAM FLOWS OUT OF THE BUILDING AND DOWN A GULLY.
Available exits are W, U, E, S, D, N, Q,
檔案名隨便改,讓系統找不到
輸出結果:
IOException!
Exception in thread “main” java.lang.NullPointerException
at introduceIo.Main.main(Main.java:31)