2014-01-28 46 views
5

所以我寫了一些代碼,並且Netbeans建議轉換爲在我實例化sc的同一行上嘗試使用資源。這個建議在我把while循環後面的sc.close()的時候彈出來。我不太明白爲什麼這種密切的操作很糟糕。打開和關閉像這樣的流是什麼錯誤?

 public static void main(String[] args) { 
     try{ 
      Scanner sc = new Scanner(new File(args[0])); 
      while(sc.hasNext()){ 
       System.out.println(sc.nextLine()); 
      } 
      sc.close(); 

     } catch(FileNotFoundException e){ 
      System.out.println("Het bestand kon niet gevonden worden."); 
     } catch(Exception e){ 
      System.out.println("Onbekende Fout"); 
     } 
    } 
+1

有一種叫做'finally'的東西。 – devnull

+0

它不在while循環中關閉操作... – BURNS

回答

1

的問題是,你可能不關閉sc,如果你從你try塊返回或發生異常。

的嘗試,與資源的版本是最好的,如果你使用的是Java 7或更高版本:

public static void main(String[] args) { 
    try (Scanner sc = new Scanner(new File(args[0]))) { 
     while(sc.hasNext()){ 
      System.out.println(sc.nextLine()); 
     } 
    } catch(FileNotFoundException e){ 
     System.out.println("Het bestand kon niet gevonden worden."); 
    } catch(Exception e){ 
     System.out.println("Onbekende Fout"); 
    } 
} 

掃描儀將得到自動的關閉。

如果你有使用Java 6或更早的版本,然後嘗試/最後:

public static void main(String[] args) { 
    Scanner sc = null; 
    try { 
     sc = new Scanner(new File(args[0])); 
     while(sc.hasNext()){ 
      System.out.println(sc.nextLine()); 
     } 
    } catch(FileNotFoundException e){ 
     System.out.println("Het bestand kon niet gevonden worden."); 
    } catch(Exception e){ 
     System.out.println("Onbekende Fout"); 
    } 
    finally { 
     if (sc != null) { 
      try { 
       sc.close(); 
      } 
      catch (Exception) { 
      } 
     } 
    } 
} 

注意,在try /最後的版本中,我們聲明sctry塊外面,將其設置爲null,然後在finally(無論在try中會發生什麼),我們關閉它,如果它不是null而不允許該操作拋出異常(因爲我們可能已經處於拋出異常的過程中,不想打斷那個)。

+0

我的教導給出了這個示例代碼: \t嘗試{0}最佳和=新掃描儀(新文件(bestandsnaam)); openengelukt = true; (bestand.hasxtLine()){ System.out.println(bestand.nextLine()); } bestand.close(); console.close(); 看着它,看起來她也犯了錯誤,因爲它應該是自閉的? – BURNS

+0

這不是一個錯誤,它是一個方便。 – TwoThe

+1

這是一個錯誤,代碼是錯誤的。我剛剛花了上週的時間來梳理一個龐大的項目,並修復這樣的錯誤,因爲這些東西像篩子一樣泄漏了資源。 –

1

close()只應在您完成資源時完成。如果您在閱讀時發生異常,則您將跳出該塊並跳過close()
添加finally塊,這意味着它要麼捕獲該異常然後調用close()或完成try塊,然後調用close()

 Scanner sc = null; 
    try{ 
     sc = new Scanner(new File(args[0])); 
     while(sc.hasNext()){ 
      System.out.println(sc.nextLine()); 
     } 

    } catch(FileNotFoundException e){ 
     System.out.println("Het bestand kon niet gevonden worden."); 
    } catch(Exception e){ 
     System.out.println("Onbekende Fout"); 
    } 
    finally 
    { 
     if (sc != null) 
      sc.close() 
    } 

,或者如果您使用的是Java 7 try-with-resources是因爲它會做的更簡單爲你關閉。

try (Scanner sc = new Scanner(new File(args[0]));) 
{ 
    .... 
+1

爲什麼downvote? –

+0

不是我的downvote,但不會編譯。 'sc'在'finally'塊中是一個未定義的符號。 –

+1

好點:)更新 –

1

從Java教程上Try with resources

試戴與資源語句聲明一個 或多個資源的try語句。資源是在程序完成後必須關閉的對象。 try-with-resources語句 可確保在語句結束時關閉每個資源。任何實現java.lang.AutoCloseable的對象,其中包含所有實現java.io.Closeable的對象,其中包含所有 可用作資源。

static String readFirstLineFromFile(String path) throws IOException { 
    try (BufferedReader br = 
        new BufferedReader(new FileReader(path))) { 
     return br.readLine(); 
    } 
} 

在這個例子中,在try-與資源 聲明中宣佈的資源是一個BufferedReader。聲明語句在try關鍵字後面的括號內出現 。類別 Java SE 7及更高版本中的BufferedReader實現接口 java.lang.AutoCloseable。由於BufferedReader實例在使用try-with-resource語句中聲明的 中,無論try語句是正常還是突然地完成 (由於BufferedReader.readLine拋出IOException異常),它將被關閉 。

所以嘗試資源將照顧關閉您的資源。您不需要再寫close()

3

問題是,如果在方法的打開和關閉返回之間有任何內容或拋出異常,那麼關閉不會被調用。

使用try-with-resources(或pre-Java 7 try-finally)進行關閉確保每次都關閉流。

+0

如果他不寫sc.close()會怎麼樣。爲什麼我們不會得到資源開放的例外情況?如果我們不能執行sc.close(),爲什麼它不像在代碼中沒有sc.close()那樣? – TheLostMind

+1

try-with-resources是Java 7,而不是8 –

+0

@RossDrew oops,意思是在那裏輸入7 ...不知道爲什麼我把8.修復它謝謝。 –

0

假設讀取輸入失敗在該行無論出於何種原因:

System.out.println(sc.nextLine()); 

,則拋出異常並執行catch (Exception e)塊。在這種情況下,您的Scanner將不會關閉。

要關閉Scanner在所有情況下,你應該移動sc.close()語句finally塊:

try { 
    Scanner sc = new Scanner(new File(args[0])); 
    while(sc.hasNext()){ 
     System.out.println(sc.nextLine()); 
    } 
} catch(FileNotFoundException e){ 
    System.out.println("Het bestand kon niet gevonden worden."); 
} catch(Exception e){ 
    System.out.println("Onbekende Fout"); 
} finally { 
    if (sc != null) { 
     try { 
      sc.close(); 
     } 
     catch (Exception) { } 
    } 
} 

爲此,您現在可以使用嘗試與 - 資源的快捷方式介紹了Java 7:

try (Scanner sc = new Scanner(new File(args[0]))) { 
    while(sc.hasNext()){ 
     System.out.println(sc.nextLine()); 
    } 
} catch(FileNotFoundException e){ 
    System.out.println("Het bestand kon niet gevonden worden."); 
} catch(Exception e){ 
    System.out.println("Onbekende Fout"); 
} 
2

這種方式更好。使用finally提供安全操作。

Scanner sc=null; 
    try{ 
     sc = new Scanner(new File(args[0])); 
     while(sc.hasNext()){ 
      System.out.println(sc.nextLine()); 
     }   

    } catch(FileNotFoundException e){ 
     System.out.println("Het bestand kon niet gevonden worden."); 
    } catch(Exception e){ 
     System.out.println("Onbekende Fout"); 
    } finally { 
     if(sc!=null){ 
     sc.close(); 
     } 
    } 
+0

從'try'塊中移除'sc.close()'。 –

+0

@ T.J.Crowder ohh謝謝你指點我。 –

0

如果在open()close()之間返回任何內容,則該方法拋出異常,則不會調用close()。做一件事,嘗試評論這段代碼,並用另一段代碼替換,以檢查是否可以用該代碼覆蓋該錯誤。或者,使用Java 7之後發佈的try-with-resources,這將確保每次調用流時都會使用close()

+0

[鏈接](http ://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) – D3X