You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

错误原因分析

  1. 文件指针重复读取问题:readMatrixFromFile中调用getNumRows(file)时,该方法会创建新Scanner将文件所有行读取完毕并关闭,此时文件的读取指针已走到末尾。回到原方法的Scanner再调用scanner.nextLine()时,已无行可读,直接抛出NoSuchElementException。
  2. 行读取计数错误:即使没有指针问题,原代码先读取一行获取列数,再循环读取numRows行,会导致少读一行(第一行被用来获取列数,未存入矩阵)。
  3. 空指针隐患:若文件读取失败返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:27:16