Java读取双文件矩阵相乘时遇NoSuchElementException错误求助
Java矩阵乘法程序抛出NoSuchElementException异常
我正在用Java实现读取两个TXT文件中的矩阵并完成乘法运算,运算可行则将结果输出至另一个TXT文件。但运行时持续抛出以下异常:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at MM.readMatrixFromFile(MM.java:38)
at MM.main(MM.java:15)
已确认TXT文件路径正确,自查代码未发现问题,项目文件结构为根目录下直接存放MM.java、matrixA.txt、matrixB.txt,附上相关Java代码:
/* * 矩阵乘法程序:读取两个文件中的矩阵,相乘后将结果写入新文件 */ import java.io.*; import java.util.*; public class MM { public static void main(String[] args) { int[][] matrixA = readMatrixFromFile("matrixA.txt"); int[][] matrixB = readMatrixFromFile("matrixB.txt"); if (matrixA[0].length != matrixB.length) { System.out.println("Unable to perform matrix multiplication."); return; } int[][] matrixC = multiplyMatrices(matrixA, matrixB); writeMatrixToFile(matrixC, "matrixAnswer.txt"); } private static int[][] readMatrixFromFile(String filename) { try { File file = new File(filename); Scanner scanner = new Scanner(file); int numRows = getNumRows(file); int numCols = getNumCols(scanner.nextLine()); int[][] matrix = new int[numRows][numCols]; for (int i = 0; i < numRows; i++) { String[] values = scanner.nextLine().split(" "); for (int j = 0; j < numCols; j++) { matrix[i][j] = Integer.parseInt(values[j]); } } scanner.close(); return matrix; } catch (IOException e) { System.out.println("Error reading matrix from file: " + filename); return null; } } private static int[][] multiplyMatrices(int[][] matrixA, int[][] matrixB) { int numRowsA = matrixA.length; int numColsA = matrixA[0].length; int numColsB = matrixB[0].length; int[][] matrixC = new int[numRowsA][numColsB]; for (int i = 0; i < numRowsA; i++) { for (int j = 0; j < numColsB; j++) { for (int k = 0; k < numColsA; k++) { matrixC[i][j] += matrixA[i][k] * matrixB[k][j]; } } } return matrixC; } private static void writeMatrixToFile(int[][] matrix, String filename) { try { File file = new File(filename); FileWriter writer = new FileWriter(file); for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { writer.write(matrix[i][j] + " "); } writer.write("\n"); } writer.close(); } catch (IOException e) { System.out.println("Error writing matrix to file: " + filename); } } private static int getNumRows(File file) throws IOException { Scanner scanner = new Scanner(file); int numRows = 0; while (scanner.hasNextLine()) { scanner.nextLine(); numRows++; } scanner.close(); return numRows; } private static int getNumCols(String line) { return line.trim().split(" +").length; } }
错误原因分析
- 文件指针重复读取问题:
readMatrixFromFile中调用getNumRows(file)时,该方法会创建新Scanner将文件所有行读取完毕并关闭,此时文件的读取指针已走到末尾。回到原方法的Scanner再调用scanner.nextLine()时,已无行可读,直接抛出NoSuchElementException。 - 行读取计数错误:即使没有指针问题,原代码先读取一行获取列数,再循环读取
numRows行,会导致少读一行(第一行被用来获取列数,未存入矩阵)。 - 空指针隐患:若文件读取失败返回
null,后续matrixA[0].length会触发NullPointerException。
修复方案
修改readMatrixFromFile方法,仅用一个Scanner读取所有行存入列表,一次性获取行数、列数并填充矩阵,同时增加空值判断:
修改后的核心代码
public static void main(String[] args) { int[][] matrixA = readMatrixFromFile("matrixA.txt"); int[][] matrixB = readMatrixFromFile("matrixB.txt"); // 增加空值判断,避免空指针 if (matrixA == null || matrixB == null) { System.out.println("矩阵文件读取失败"); return; } if (matrixA[0].length != matrixB.length) { System.out.println("无法执行矩阵乘法:第一个矩阵的列数不等于第二个矩阵的行数"); return; } int[][] matrixC = multiplyMatrices(matrixA, matrixB); writeMatrixToFile(matrixC, "matrixAnswer.txt"); } private static int[][] readMatrixFromFile(String filename) { try { File file = new File(filename); Scanner scanner = new Scanner(file); List<String> lines = new ArrayList<>(); // 读取所有非空行到列表 while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); if (!line.isEmpty()) { lines.add(line); } } if (lines.isEmpty()) { System.out.println("文件为空:" + filename); scanner.close(); return null; } int numRows = lines.size(); int numCols = getNumCols(lines.get(0)); int[][] matrix = new int[numRows][numCols]; // 从列表中读取行填充矩阵 for (int i = 0; i < numRows; i++) { String[] values = lines.get(i).split(" +"); for (int j = 0; j < numCols; j++) { matrix[i][j] = Integer.parseInt(values[j]); } } scanner.close(); return matrix; } catch (IOException e) { System.out.println("读取文件错误:" + filename); return null; } } // 保留原getNumCols方法 private static int getNumCols(String line) { return line.trim().split(" +").length; }
说明
- 不再需要
getNumRows方法,通过列表大小直接获取行数,避免重复读取文件。 - 跳过空行,避免空行导致的列数计算错误或矩阵填充异常。
- 增加空值判断,提前终止流程并给出明确提示。
内容的提问来源于stack exchange,提问作者Rayman
相关产品推荐
相关产品推荐

