
本文详解如何从文件中读取迷宫数据(首行为行列数,后续为迷宫布局),安全、准确地将每个字符按行优先顺序存入二维 char 数组,并规避常见读取逻辑错误(如重复调用 `readline()` 导致跳行、索引越界等)。
在处理类似迷宫解析这类结构化文本文件时,关键在于精确控制文件读取节奏:第一行提取维度信息,后续每一行严格对应二维数组的一行。原代码中 while(read.readLine() != null) 与内层循环中再次调用 read.readLine() 的组合,导致每轮迭代实际消耗两行(一次被 while 判定丢弃,一次被赋值使用),从而引发跳行、末行缺失及数组未完全填充等问题。
正确的做法是:显式、单次读取每行,并将其逐字符映射到对应数组位置。以下是优化后的核心逻辑(已整合进完整可运行程序):
import java.io.*;
import java.util.*;
public class MazeLoader {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("Enter the filename of the maze: ");
String fileName = inp.nextLine().trim();
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
// 读取首行:解析行数 row 和列数 col
String firstLine = reader.readLine();
if (firstLine == null) {
throw new IOException("File is empty");
}
String[] dims = firstLine.split("\\s+");
if (dims.length < 2) {
throw new IOException("Invalid format: first line must contain 'rows cols'");
}
int row = Integer.parseInt(dims[0]);
int col = Integer.parseInt(dims[1]);
char[][] maze = new char[row][col];
// 逐行读取迷宫内容(共 row 行)
for (int i = 0; i < row; i++) {
String line = reader.readLine();
if (line == null) {
throw new IOException("Unexpected end of file: expected " + row + " maze lines, got only " + i);
}
// 每行需至少包含 col 个有效字符(含空格),截取前 col 个字符确保长度匹配
if (line.length() < col) {
throw new IOException("Line " + (i + 2) + " is too short: expected at least " + col + " characters, got " + line.length());
}
for (int j = 0; j < col; j++) {
maze[i][j] = line.charAt(j);
}
}
// 验证并打印结果(格式化输出,清晰展示二维结构)
System.out.println("\nLoaded maze (" + row + "x" + col + "):");
for (int i = 0; i < row; i++) {
System.out.println(Arrays.toString(maze[i]));
}
} catch (NumberFormatException e) {
System.err.println("Error: Invalid numeric value in first line.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("IO Error: " + e.getMessage());
e.printStackTrace();
} finally {
inp.close();
}
}
}✅ 关键改进点说明:
- 单次读取,明确控制:使用 for (int i = 0; i
- 边界安全校验:检查 line == null 防止 EOF 异常,验证每行长度 ≥ col,确保不越界访问 charAt(j);
- 资源自动管理:try-with-resources 确保 BufferedReader 正确关闭;
- 健壮性增强:对空文件、格式错误、数字解析失败等场景提供清晰错误提示。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 输入文件中迷宫行的字符(包括 #、空格、换行符前的空白)必须严格对齐,本方案按原始字符位置(而非 split() 后的非空字段)填充,因此能正确保留空格分隔的布局(如示例中的 "# # #####");
- 若需忽略行首尾空白或合并连续空格,应在 line.charAt(j) 前对 line 执行 trim() 或正则预处理,但会改变原始坐标映射,需根据实际需求权衡;
- 本实现假设文件编码为平台默认(通常 UTF-8),如需指定编码,请使用 new InputStreamReader(new FileInputStream(...), StandardCharsets.UTF_8) 构造 BufferedReader。
通过以上设计,程序能稳定、可预测地将结构化文本文件转换为内存中的二维字符网格,为后续迷宫求解(如 DFS/BFS)提供坚实的数据基础。










