2013-10-19 107 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