java - 扫描程序类NoSuchElementFoundException

时间:2013-10-19 07:33:09

标签: java java.util.scanner java-io

我正在尝试使用Java编写程序。我的代码如下

class Main{
    static Employee getData() throws IOException {
        BufferedReader rdr = new BufferedReader(
                            new InputStreamReader(
                            new DataInputStream(System.in)
                            ));
        System.out.printf("Enter Employee ID : ");
        int tmpid = Integer.parseInt(rdr.readLine());
        System.out.printf("Enter Employee Name : ");
        String tmpname = rdr.readLine();
        System.out.printf("Enter Employee Salary : ");
        int tmpsalary = Integer.parseInt(rdr.readLine());
        rdr.close();
        return new Employee(tmpid, tmpname, tmpsalary);
    }   
    public static void main(String []args){
        boolean b = false;  
        String path = null;
        Scanner s = new Scanner(System.in);
        File file = null;
        try {
            System.out.printf("Enter path to save your file : ");
            path = s.next();
            file = new File(path);
            if (!(file.createNewFile()))
                System.out.println("Error creating file");
        } catch (Exception ie) {
            System.err.println("Exception : " + ie);
        }       


        do{
            try {
                Employee rec = Main.getData();
                ObjectOutputStream dos = new ObjectOutputStream(new FileOutputStream(file));
                dos.writeObject(rec);
                dos.close();
                System.out.printf("Add more records [true/false]? ");
                s = new Scanner(System.in);
                    int tmp = s.nextInt();
            } catch (Exception ioe) {
                System.err.println("Exception : " + ioe);
            }

        }while(b);
    }
}

当我运行这个程序时,第二次执行s.nextInt()时会得到NoSuchElementFoundException。我尝试了所有可能的方法但没有结果。这边有什么问题?

2 个答案:

答案 0 :(得分:2)

除非你打算用它做一些有用的事情,否则永远不会捕获异常。

我得到了它的工作。这是相当直接的。

Enter path to save your file : myfile.bin
Enter Employee ID : 99
Enter Employee Name : Rick Hightower
Enter Employee Salary : 99
Add more records [true/false]? true
Enter Employee ID : 77
Enter Employee Name : Dippy Do
Enter Employee Salary : 88
Add more records [true/false]? false

以下是我所拥有的: ...

public static class Employee implements  Serializable {

    int id;
    String name;
    int salary;

    public Employee(int id, String name, int salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

}

static Employee getData() throws IOException {
    BufferedReader rdr = new BufferedReader(
            new InputStreamReader(
                    new DataInputStream(System.in)
            ));
    System.out.printf("Enter Employee ID : ");
    int tmpid = Integer.parseInt(rdr.readLine());
    System.out.printf("Enter Employee Name : ");
    String tmpname = rdr.readLine();
    System.out.printf("Enter Employee Salary : ");
    int tmpsalary = Integer.parseInt(rdr.readLine());
    //rdr.close(); this is why... you broke it :)
    return new Employee(tmpid, tmpname, tmpsalary);
}

public static void main(String []args) throws Exception {
    boolean moreRecords = true;
    String path = null;
    Scanner scanner = new Scanner(System.in);
    File file = null;
    System.out.printf("Enter path to save your file : ");
    path = scanner.next();
    file = new File(path);


    while (moreRecords) {
        Employee rec = Main.getData();
        ObjectOutputStream dos = new ObjectOutputStream(new FileOutputStream(file));
        dos.writeObject(rec);
        dos.close();
        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

主要是你的代码,其中一些部分被删除了。

你遇到的最大问题是关闭输入流。

static Employee getData() throws IOException {
    BufferedReader rdr = new BufferedReader(
            new InputStreamReader(
                    new DataInputStream(System.in)
            ));
    System.out.printf("Enter Employee ID : ");
    int tmpid = Integer.parseInt(rdr.readLine());
    System.out.printf("Enter Employee Name : ");
    String tmpname = rdr.readLine();
    System.out.printf("Enter Employee Salary : ");
    int tmpsalary = Integer.parseInt(rdr.readLine());
    //rdr.close(); this is why... you broke it :)       <-------------------SEE
    return new Employee(tmpid, tmpname, tmpsalary);
}

Java I / O流使用装饰器模式,因此它只是将close调用委托给内部流。

解决了这个问题。您的代码存在很多问题。

如果您使用的是JDK 1.7或更高版本,它将为您关闭该文件。

    while (moreRecords) {
        Employee rec = Main.getData();

        try ( ObjectOutputStream dos =
                     new ObjectOutputStream(
                             new FileOutputStream(file) ) ) {

            dos.writeObject(rec);

        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

如果您使用的是JDK 1.6或JDK 1.5:

    while (moreRecords) {
        Employee rec = Main.getData();

        ObjectOutputStream dos = null;
        try {
            dos = new ObjectOutputStream(
                            new FileOutputStream(file) );
            dos.writeObject(rec);

        } finally {
           if ( dos!=null  ) {
                dos.close();
           }
        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

此外,您的程序应该对用户输入进行更多验证。扫描仪可以按如下方式执行此操作:

public static class Employee implements  Serializable {

    private int id;
    private String name;
    private BigDecimal salary;

    public Employee(int id, String name, BigDecimal salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

}

static Employee getData(Scanner scanner) throws IOException {

    System.out.printf("Enter Employee ID : ");
    while ( !scanner.hasNextInt() ) {
        System.out.println("Employee IDs are numbers only");
        scanner.next();
    }

    int employeeId = scanner.nextInt();

    System.out.printf("Enter Employee Name : ");
    String name = scanner.next();


    System.out.printf("Enter Employee Salary : ");

    while ( !scanner.hasNextBigDecimal() ) {
        System.out.println("Employee salaries are decimals " +
                "not random gak");
        scanner.next();
    }
    BigDecimal salary = scanner.nextBigDecimal();

    return new Employee(employeeId, name, salary);
}


public static void main(String []args) throws Exception {
    boolean moreRecords = true;
    String path = null;
    Scanner scanner = new Scanner(System.in);
    File file = null;
    System.out.printf("Enter path to save your file : ");
    path = scanner.next();
    file = new File(path);


    while (moreRecords) {
        Employee rec = Main.getData(scanner);

        try ( ObjectOutputStream dos =
                      new ObjectOutputStream(
                            new FileOutputStream(file) ) ) {
            dos.writeObject(rec);

        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();

现在输入/输出更像是这样:

Enter path to save your file : asdfasdf
Enter Employee ID : 9a
Employee IDs are numbers only
99
Enter Employee Name : Rick
Enter Employee Salary : aa
Employee salaries are decimals not random gak
99.99
Add more records [true/false]? false

扫描程序强制最终用户输入正确类型的数据。 您可以将它与正则表达式结合使用以匹配名称等模式。

我扩展了示例,并添加了一些关于扫描仪的讨论。

http://rick-hightower.blogspot.com/2013/10/java-scanner-example.html

答案 1 :(得分:1)

输入用尽时,nextInt(), NoSuchElementFoundException会出现。因此,请检查您在提示时提供的输入。