2014-01-28 30 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