
本文详解如何从文件中读取迷宫尺寸与布局,安全、准确地将每行字符载入指定大小的二维 char 数组,避免重复调用 `readline()` 导致的跳行与越界问题,并提供健壮、可复用的代码实现。
在处理类似迷宫解析等场景时,需严格按格式读取文件:首行为两个整数(行数 row 和列数 col),随后 row 行为实际布局数据。关键挑战在于——不能多次无序调用 BufferedReader.readLine(),否则会跳过有效行,导致数组填充错位、末行缺失或 NullPointerException。
原始代码中存在两个核心错误:
- while(read.readLine() != null) 消耗了第一行迷宫数据,造成后续循环少读一行;
- 内层循环使用 i
- 外层 while 与内层 for 混用 readLine(),逻辑耦合混乱,难以维护。
✅ 正确做法是:用单一 for 循环控制行索引 i,每轮只调用一次 readLine() 获取当前行,并立即解析填充到 arr[i] 中。同时加入 line != null 防御性检查,提升鲁棒性。
以下是优化后的完整实现:
立即学习“Java免费学习笔记(深入)”;
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.next();
File fileObj = new File(fileName);
System.out.println("File " + fileName + " has been entered. Solving:\n");
try (BufferedReader read = new BufferedReader(new FileReader(fileObj))) {
// 读取首行:解析 row 和 col
String rcLine = read.readLine();
if (rcLine == null) {
throw new IOException("Invalid file: missing dimension line");
}
String[] rc = rcLine.trim().split("\\s+");
if (rc.length < 2) {
throw new IOException("Invalid dimension format: expected 'rows cols'");
}
int row = Integer.parseInt(rc[0]);
int col = Integer.parseInt(rc[1]);
char[][] maze = new char[row][col];
// 逐行读取并填充二维数组(共 row 行)
for (int i = 0; i < row; i++) {
String line = read.readLine();
if (line == null) {
throw new IOException("Unexpected end of file: missing row " + i);
}
// 截取前 col 个字符(兼容空格/制表符等分隔),避免 IndexOutOfBoundsException
int len = Math.min(col, line.length());
for (int j = 0; j < len; j++) {
maze[i][j] = line.charAt(j);
}
// 若某行过短,剩余位置可设为默认值(如 ' ' 或 '\0'),此处保持原字符不变(已初始化为 '\0')
// 如需补空格:for (int j = len; j < col; j++) maze[i][j] = ' ';
}
// 验证输出(可选)
System.out.println("Loaded maze (" + row + "x" + col + "):");
for (char[] rowArr : maze) {
System.out.println(Arrays.toString(rowArr));
}
} catch (IOException e) {
System.err.println("Error loading maze: " + e.getMessage());
e.printStackTrace();
} finally {
inp.close();
}
}
}? 关键注意事项:
- ✅ 使用 try-with-resources 确保 BufferedReader 自动关闭;
- ✅ trim().split("\\s+") 更健壮地处理多空格、首尾空格;
- ✅ 每次 readLine() 仅调用一次,且与行号 i 严格一一对应;
- ✅ 添加 null 和长度校验,防止运行时异常;
- ✅ 对 line.length()
- ❌ 避免在循环条件与循环体内重复调用 readLine();
- ❌ 不要硬编码 row-1,应始终以 row 为上限。
该方案逻辑清晰、边界安全、易于调试与扩展(例如后续支持注释行、忽略空白行等),是 Java 文件驱动二维结构初始化的标准实践。










