如何向文件写入非文本内容?游戏存档需存储int、String等类型数据
Hey there! Let's get your game save functionality sorted out. Right now your code only initializes a FileOutputStream, which is a great base layer—but we need to wrap it with classes that can handle int, boolean, String and other types directly. Here are two solid approaches tailored for game save systems:
方案1:使用DataOutputStream(适合简单结构化存档)
DataOutputStream is built specifically to write primitive Java types (like int, boolean) and strings directly to a file, and you can read them back in the exact same order with DataInputStream. It's perfect if you want a straightforward, low-level way to structure your save data.
修改后的保存代码
private void saveGame() { // 示例游戏数据,替换成你实际的游戏状态 int playerScore = 1500; boolean isGameCompleted = false; String playerName = "BasketballLegend"; try (FileOutputStream fos = new FileOutputStream("F:/BLAISE RECOV/Java/Finished Games/BasketBall/BasketballGame_saves/Games"); DataOutputStream dos = new DataOutputStream(fos)) { // 按固定顺序写入各类数据 dos.writeInt(playerScore); dos.writeBoolean(isGameCompleted); dos.writeUTF(playerName); // 用writeUTF保存字符串,能正确处理Unicode字符 System.out.println("Game saved successfully!"); } catch (IOException e) { System.err.println("Problem writing to the save file: " + e.getMessage()); e.printStackTrace(); } }
对应的读取代码(存档肯定要读回来对吧?)
private void loadGame() { try (FileInputStream fis = new FileInputStream("F:/BLAISE RECOV/Java/Finished Games/BasketBall/BasketballGame_saves/Games"); DataInputStream dis = new DataInputStream(fis)) { // 必须严格遵循写入时的顺序 int loadedScore = dis.readInt(); boolean loadedCompleted = dis.readBoolean(); String loadedName = dis.readUTF(); // 用读取到的数据恢复游戏状态 System.out.println("Loaded Score: " + loadedScore); System.out.println("Game Completed: " + loadedCompleted); System.out.println("Player Name: " + loadedName); } catch (IOException e) { System.err.println("Problem reading the save file: " + e.getMessage()); e.printStackTrace(); } }
方案2:使用ObjectOutputStream(序列化,适合复杂游戏对象)
If your game has lots of related state data (like multiple player stats, level progress, inventory items), wrap all that data into a single custom class that implements the Serializable interface. You can then serialize the entire object to a file in one go—no need to manually manage each field's read/write order.
1. 创建可序列化的游戏存档类
import java.io.Serializable; // 必须实现Serializable接口才能被序列化 public class GameSave implements Serializable { // 可选:添加序列化版本UID,避免类结构小变化时读取失败 private static final long serialVersionUID = 1L; // 所有需要保存的游戏数据字段 public int playerScore; public boolean isGameCompleted; public String playerName; public int currentLevel; // 构造方法,用于初始化存档数据 public GameSave(int score, boolean completed, String name, int level) { this.playerScore = score; this.isGameCompleted = completed; this.playerName = name; this.currentLevel = level; } }
2. 序列化保存与读取代码
// 保存方法 private void saveGameWithSerialization() { GameSave saveData = new GameSave(1500, false, "BasketballLegend", 3); try (FileOutputStream fos = new FileOutputStream("F:/BLAISE RECOV/Java/Finished Games/BasketBall/BasketballGame_saves/Games.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(saveData); System.out.println("Game saved via serialization!"); } catch (IOException e) { System.err.println("Serialization save error: " + e.getMessage()); e.printStackTrace(); } } // 读取方法 private void loadGameWithSerialization() { try (FileInputStream fis = new FileInputStream("F:/BLAISE RECOV/Java/Finished Games/BasketBall/BasketballGame_saves/Games.ser"); ObjectInputStream ois = new ObjectInputStream(fis)) { GameSave loadedData = (GameSave) ois.readObject(); // 用加载的数据恢复游戏状态 System.out.println("Loaded Level: " + loadedData.currentLevel); System.out.println("Loaded Score: " + loadedData.playerScore); } catch (IOException | ClassNotFoundException e) { System.err.println("Serialization load error: " + e.getMessage()); e.printStackTrace(); } }
实用小贴士
- 我用了try-with-resources语法(Java 7+),它会自动关闭流,不用手动调用
close(),彻底避免资源泄漏。 - 使用
DataOutputStream时,读取顺序必须和写入顺序完全一致,否则会得到错乱的数据。 - 序列化时,所有字段的类型也必须是可序列化的(基本类型、String、其他
Serializable类都没问题)。 - 如果你的目标保存目录不存在,记得先创建它:
new File("your/directory/path").mkdirs();
内容的提问来源于stack exchange,提问作者user9010885

