2013-10-19 73 views
1

我正在尝试Java中的程序。我的代码去如下java - 扫描仪类NoSuchElementFoundException

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。我尝试了所有可能的方法,但没有结果。这里有什么问题?

+0

你问'添加更多的记录[真/假]'所以对于什么是你进入的回应? – Maximin

+0

请参阅@Adaam在他自己的问题中发布的评论。在这里我发现我的情况与环境问题无关。 – iammurtaza

+0

对不起'添加更多记录[true/false]?'这是我实际上想要编写的程序的一部分,但采取's.nextBoolean()'也失败了,所以我尝试了's.nextInt()' – iammurtaza

回答

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流使用装饰器模式,因此它只是将关闭调用委托给内部流。

解决了这个问题。你的代码有很多问题。

如果您使用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

+0

我没有得到您为Java 7版本编写的代码。 Java 7中引入的try block中的新特性是什么? – iammurtaza

+0

没有最后的块。你把“可关闭的”(Closable接口)放在try父母'try(ObjectOutputStream dos = ...){'那么你不需要finally块。我也是新手。我经常使用finally块。由于FILE_DESCRIPTORS是一个有限的资源(10K到300K,而不是更多,它取决于操作系统设置),所以如果您正在处理文件,则必须执行一个或另一个操作。 – RickHigh

1

nextInt(),NoSuchElementFoundException发生在输入耗尽时。因此请检查您在提示时输入的内容。

+0

我输入一个整数,我确信这一点。 – iammurtaza