如何用Java的Scanner与BufferedWriter读写指定格式的游戏数据?
用Scanner和BufferedWriter实现游戏数据读写的最简方案
绝对可以用你已经掌握的Scanner和BufferedWriter完成需求!完全不用学习新的API,刚好适配你指定的存储格式,下面直接给你可运行的代码和关键说明:
第一步:先定义你的Item类
首先咱们把Item对象的结构明确下来,用一个effectValue字段统一存储伤害或治疗值,通过itemType区分用途:
class Item { String itemType; // 比如"weapon"或"potion",用来区分是伤害还是治疗 String itemName; int itemCount; int effectValue; // 存储itemDamage或itemHealing的值 // 构造器(方便初始化) public Item(String itemType, String itemName, int itemCount, int effectValue) { this.itemType = itemType; this.itemName = itemName; this.itemCount = itemCount; this.effectValue = effectValue; } }
第二步:写入游戏数据(BufferedWriter实现)
用BufferedWriter按你要求的格式拼接所有数据,每次保存直接覆盖原有文件(FileWriter默认就是覆盖模式):
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class GameSaveHandler { public static void saveGameData(int gameStage, String playerName, int playerHealth, int playerArmour, Item[] playerInventory) throws IOException { // 使用try-with-resources自动关闭流,不用手动写close() try (BufferedWriter writer = new BufferedWriter(new FileWriter("game_save.txt"))) { // 先写入基础游戏数据 writer.write(gameStage + " " + playerName + " " + playerHealth + " " + playerArmour + " "); // 遍历物品栏,逐个写入每个Item的信息 for (int i = 0; i < playerInventory.length; i++) { Item item = playerInventory[i]; if (item == null) continue; // 跳过空物品槽 // 写入SLOT标记 + 物品属性 + END标记 writer.write("SLOT" + (i + 1) + " "); writer.write(item.itemType + " " + item.itemName + " " + item.itemCount + " " + item.effectValue + " "); writer.write("END" + (i + 1) + " "); } // 最后写入终止标记STOP writer.write("STOP"); } } }
第三步:读取游戏数据(Scanner实现)
用Scanner按顺序解析文件内容,直到遇到STOP标记为止:
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class GameLoadHandler { public static void loadGameData() throws FileNotFoundException { try (Scanner scanner = new Scanner(new File("game_save.txt"))) { // 读取基础数据 int gameStage = scanner.nextInt(); String playerName = scanner.next(); // 注意:如果玩家名字包含空格,需要改用nextLine()并处理换行符 int playerHealth = scanner.nextInt(); int playerArmour = scanner.nextInt(); // 初始化物品栏数组 Item[] playerInventory = new Item[5]; int currentSlot = 0; // 循环读取直到遇到STOP while (scanner.hasNext()) { String token = scanner.next(); if ("STOP".equals(token)) { break; } // 识别物品槽开始标记 if (token.startsWith("SLOT")) { // 读取物品属性 String itemType = scanner.next(); String itemName = scanner.next(); int itemCount = scanner.nextInt(); int effectValue = scanner.nextInt(); // 跳过END标记(不需要存储) scanner.next(); // 将物品存入数组 playerInventory[currentSlot] = new Item(itemType, itemName, itemCount, effectValue); currentSlot++; } } // 这里可以把读取到的数据赋值给你的游戏对象,示例打印输出 System.out.println("=== 加载的游戏数据 ==="); System.out.println("游戏阶段:" + gameStage); System.out.println("玩家名称:" + playerName); System.out.println("玩家生命值:" + playerHealth); System.out.println("玩家护甲值:" + playerArmour); System.out.println("物品栏:"); for (Item item : playerInventory) { if (item != null) { String effectLabel = "weapon".equals(item.itemType) ? "伤害值" : "治疗值"; System.out.printf("- %s(%s):数量=%d,%s=%d%n", item.itemName, item.itemType, item.itemCount, effectLabel, item.effectValue); } } } } }
关键注意事项
- 玩家名字的空格问题:如果你的
playerName可能包含空格(比如"John Doe"),不能直接用scanner.next(),需要在读完playerArmour后调用scanner.nextLine()跳过换行符,再用scanner.nextLine()读取完整名字;同时写入时可以给名字加引号,读取时处理引号逻辑,不过如果名字无空格,当前代码完全没问题。 - 空物品槽处理:代码里加了
if (item == null) continue;,如果物品槽为空就跳过写入,读取时也会保留数组对应位置为null,符合实际游戏场景。 - 自动关闭流:使用
try-with-resources语法,Java会自动帮你关闭BufferedWriter和Scanner,避免资源泄漏,比手动写close()更安全。
替代方案(如果真的想简化)
其实上面的方案已经是最贴合你需求且无需学习新内容的了,但如果还要更简单,可以考虑用序列化,但需要让你的相关类实现Serializable接口,虽然代码更少,但你需要理解序列化的概念,反而不如当前方案直接。所以优先推荐你用Scanner+BufferedWriter的方案,完全符合你的时间要求。
内容的提问来源于stack exchange,提问作者TheTornadoStorm
相关产品推荐
相关产品推荐

