【问题标题】:Reading Data from Multiple txt Files in JavaJava从多个txt文件中读取数据
【发布时间】:2012-01-13 16:57:59
【问题描述】:

我是一名正在学习计算机科学入门的初学者,我正在使用 java。尝试在 getLetterGrade 方法中读取多个 txt 文件时,我在此程序中收到以下错误:

线程“主”java.lang.IllegalStateException 中的异常:扫描仪已关闭

import java.util.Scanner;
import java.io.*;

public class Exam
{
    private int grade;
    private float examAvg;
    private String name;
    private File exam1Data;
    private File exam2Data;
    private File namesData;
    private Scanner inFileExam1;
    private Scanner inFileExam2;
    private Scanner inFileName;

    //constructor
    public Exam() throws IOException
    {
        exam1Data = new File("exam1.txt");
        exam2Data = new File("exam2.txt");
        namesData = new File("names.txt");
        inFileExam1 = new Scanner(exam1Data);
        inFileExam2 = new Scanner(exam2Data);
        inFileName = new Scanner(namesData);
    }

public float getExam1Avg()
{
examAvg = 0;

while (inFileExam1.hasNext()) {
grade = inFileExam1.nextInt();
examAvg += grade;
}
inFileExam1.close();
examAvg = (float)(examAvg / 25.0);
return examAvg;
}

public float getExam2Avg()
{
examAvg = 0;

while (inFileExam2.hasNext()) {
grade = inFileExam2.nextInt();
examAvg += grade;
}
inFileExam2.close();
examAvg = (float)(examAvg / 25.0);
return examAvg;
}

    //method that finds the letter grade given a student name and
    //the exam number
    public char getLetterGrade(String inputName, int examNum)
    {
        char letter;
        int count = 1;

        //inputName = inputName.toLowerCase();

        do {
            if (inFileName.hasNext()){
                name = inFileName.nextLine();
            }
            count++;
        } while (inFileName.hasNext() && !name.equalsIgnoreCase(inputName));

        inFileName.close();

        if (!name.equalsIgnoreCase(inputName)) {
            return 'x';
        }

        if (examNum == 1) {
            for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
                grade = inFileExam1.nextInt();
            }
            inFileExam1.close();
        }
        else if (examNum == 2) {
            for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
                grade = inFileExam2.nextInt();
            }
            inFileExam2.close();
        }
        else {
            return 'x';
        }

        if (grade >= 90) {
            letter = 'A';
        }
        else if (grade < 90 && grade >= 80) {
            letter = 'B';
        }
        else if (grade < 80 && grade >= 70) {
            letter = 'C';
        }
        else if (grade < 70 && grade >= 60) {
            letter = 'D';
        }
        else {
            letter = 'F';
        }

        return letter;
    }
}

错误发生在以下行:

for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {

请帮忙!!

这里是主类:

import java.util.Scanner;
import java.io.*;

public class ExamAverages
{
public static void main(String[] args) throws IOException
{
Exam exam = new Exam();
System.out.println(exam.getExam1Avg());
System.out.println(exam.getExam2Avg());
System.out.println(exam.getLetterGrade("name", 1));
}

【问题讨论】:

  • inFileExam*这两个文件中的数据是什么?
  • exam1.txt 数据:67 56 90 77 45 87 23 12 87 89 96 44 55 66 22 88 99 77 59 100 2 47 60 8 81exam2.txt 数据:76 34 11 77 44 33 77 88 97 65 79 71 72 45 54 68 32 83 49 88 79 81 93 58 75 顺便说一句,所有数字都写在不同的行上。不知道这是否重要。
  • 老兄,你只是让你的帖子更加复杂和难以阅读。坚持主要问题
  • 您能否解释一下您的代码应该如何处理所有这些文件

标签: java file input


【解决方案1】:

你正在关闭你的扫描仪

inFileName.close();

然后尝试再次使用它而不像这样打开:

inFileName = new Scanner(..); 

EDIT1 它对我来说并没有失败,但也许我错过了一些东西(我仍然不知道您究竟愿意阅读这些文件,它们之间的关系如何)

public char getLetterGrade(String inputName, int examNum) {
    char letter;
    int count = 0;

    do {
        if (inFileName.hasNext()) {
            name = inFileName.nextLine();
        }
        count++;
    } while (inFileName.hasNext() && !name.equalsIgnoreCase(inputName));

    if (!name.equalsIgnoreCase(inputName)) {
        return 'x';
    }

    if (examNum == 1) {
        for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
            grade = inFileExam1.nextInt();
        }
        inFileExam1.close();
    } else if (examNum == 2) {
        for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
            grade = inFileExam2.nextInt();
        }
        inFileExam2.close();
    } else {
        return 'x';
    }

    if (grade >= 90) {
        letter = 'A';
    } else if (grade < 90 && grade >= 80) {
        letter = 'B';
    } else if (grade < 80 && grade >= 70) {
        letter = 'C';
    } else if (grade < 70 && grade >= 60) {
        letter = 'D';
    } else {
        letter = 'F';
    }

    return letter;
}

【讨论】:

  • 不是扫描仪有问题。这是 inFileExam1 扫描仪的问题。
  • 然后提供所有代码,我们将看到它。否则这个异常只是因为多个 Scanner 实例被实例化而没有关闭它们
  • 我还有其他方法,我也加一下
  • 如果您只是删除/注释掉“inFileName.close();”,请在您的代码中一切都会正常工作,因为我们不确定您存储的文件中有什么,所以我们无法调试它(我不能),但只要我现在尝试读取文件,获取输出,它就可以工作,只需评论/删除这一行
  • hmm.. 我删除了它,但它仍然无法正常工作。我现在得走了。我回家后会回来看看。感谢大家迄今为止的帮助,我很感激,希望你能继续帮助我!!
【解决方案2】:

首先,每次读取一行时,您都会重置grade,而您并没有对它做任何事情,因此这部分代码是无用的。

但要回答你的问题:

根据 API,Scanner 仅在对象使用 Scanner.close() 关闭或被系统以某种方式关闭后返回 IllegalStateException

尝试将 inFileExam1Scanner 声明移到您使用它的位置旁边,如下所示:

if (examNum == 1) {
        inFileExam1 = new Scanner(exam1Data); // Add this
        for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
            grade = inFileExam1.nextInt();
        }
        inFileExam1.close();
    }
    else if (examNum == 2) {
        inFileExam2 = new Scanner(exam2Data); // And this
        for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
            grade = inFileExam2.nextInt();
        }
        inFileExam2.close();
    }
}

【讨论】:

  • 我完全按照您的方式添加了代码,但现在我收到以下运行时错误:线程“main”中的异常 java.lang.RuntimeException:无法编译的源代码 - 未报告的异常 java.io。 FileNotFoundException;必须被抓住或被宣布被抛出...... :(
  • 使方法抛出一个IOException 像这样:getLetterGrade(...) throws IOException {
  • 我在构造函数中注释掉了 inFileExam1 和 inFileExam2 分配,并且我还为 getLetterGrade 方法添加了“抛出 IOException”......但现在我得到一个不同的错误:线程“main”中的异常java.lang.NullPointerException ...它说错误首先发生在以下行:while (inFileExam1.hasNext()){
  • 您的意思是while(inFileName.hasNext() {?否则我在代码中看不到那行。是否有另一个班级正在运行这个?如果是这样,请使用添加的代码编辑问题。
  • 我只是把它改成了 while (inFileName.hasNextInt(){ 但我得到了同样的错误。我用主类和我的整个代码更新了原始帖子。
【解决方案3】:

您没有包含具有您的 main 方法的代码,但我将做出有根据的猜测,您在其中构造了一个新的 Exam 对象,并多次调用 getLetterGrade。由于您在构造函数中打开Scanners,并在阅读后关闭它们,因此在您调用getLetterGrade 次您将看到IllegalStateException

如果此通灵解读不准确,能否将您的帖子更新为main(String[] args) 的内容?

编辑:在您最近一次编辑之后,我看到您在调用getLetterGrade 之前调用了getExam1Avg 方法。由于getExam1Avg 在您的Scanner 上调用close,因此在调用其他方法时会收到IllegalStateException。您需要为每个方法调用实例化一个新的扫描器,或者在每个方法完成后重置扫描器。

【讨论】:

  • 我不知道如何编辑主帖...但我只是在制作一个考试对象并使用 System.out.println(getLetterGrade("name", 1));
  • @user1082587 在您问题的底部,左侧有一个edit 按钮。
【解决方案4】:

您的错误在getAverageExam1Avg 和另一个中。与其在getLetterGrade 方法中关闭Scanners,不如让它们保持打开状态并添加一个close 方法,如下所示:

public void close() {
    inFileName.close();
    inFileExam1.close();
    inFileExam2.close();
}

确保在该代码中添加正确的异常。

现在失败的原因是您还没有打开扫描仪。取消注释构造函数中的实例化。

如果这不起作用,我不知道会发生什么。

【讨论】:

  • 感谢大家的帮助。我拿走了构造函数以及 File 和 Scanner 字段声明。相反,我为每种方法创建了 File 和 Scanner 对象。不再有运行时错误。 :) 对于那些想知道我要做什么的人:我从用户那里获取一个字符串输入(学生姓名),并将其与 names.txt 文件中的相同字符串进行匹配,同时计算字符串下方的行数.然后我从exam1.txt 或exam2.txt 中找到对应的考试成绩(整数),它们应该位于相同的行号。
  • 它仍然无法完美运行,因为我没有得到正确的结果,但我认为我应该能够从这里处理它。如果我有更多的麻烦,我会告诉你们。再次感谢!
  • 是的,我刚刚将 count 变量初始化为 0,而不是像 Boris 那样初始化为 1。现在可以正常使用了。
  • 这是正确的答案吗?还是您只是对此发表评论?您应该接受解决问题的答案,但如果他们都没有接受,那就离开吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多