Java 學習記錄86 — Load Big Location and Exits Files — 5/7

張小雄
2 min readOct 18, 2021

--

承 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 測試是否正常

但這樣寫 whilecatch 會有個問題

原本用意是當 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)

本篇代碼

--

--

張小雄
張小雄

Written by 張小雄

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

No responses yet