2014-10-29 66 views
2

如果我有一个抛出FilenotFoundException的方法,因为我正在使用扫描器对象来读取文件,如果错误实际上被抛出,扫描器对象是否关闭,还是在处理异常时仍然需要这样做?我知道当我在我的方法中使用try-catch-finally块写入来处理异常时,我关闭了scanner对象,但是如果必须在捕获异常的另一个对象的方法内执行此操作,我将无法访问扫描仪对象。是在抛出异常时关闭的java扫描程序?

请保持简单的说明...显然我是新来的Java(和一般的OO)。

回答

3

如果您使用的是像这样 ​​3210 代码如果抛出异常,scanner对象时,它自身不会产生,所以没必要将其关闭。

但是最好的编码方式如下。你可以关闭最后的块。

Scanner scanner=null; 
try 
{ 
    scanner = new Scanner(new File(path)); 
    //your code here 
} 
catch(FileNotFoundException e)//either catch or throw out 
{ 
    //log it 
} 
finally 
{ 
    if(null !=scanner) 
    { 
     scanner.close(); 
    } 
} 
2

如果在执行new Scanner(File)时找不到文件,则底层的FileInputStream将不会被打开。

最后块中关闭扫描器是一种很好的做法。如果扫描仪已关闭,则关闭呼叫将不起作用。

或者您可以尝试try-with-resources构造,如果发生某种异常,它将自动关闭资源。

+1

'try-with-resources'似乎是最好的方法,因为它需要更少的代码 – superbob 2014-10-29 10:18:35

+1

@superbob它是最好的方法,而不仅仅是“少代码”:)。 – Tom 2014-10-29 10:22:02

0

我想你应该关闭扫描仪对象最后块无论你捕捉异常与否。

1

假如你这样做:

Scanner scanner = new Scanner(new File("/file/does/not/exist")); 

和构造函数抛出FileNotFoundException。首先要注意的是,构造函数不返回Scanner对象。相反,new表达式将异常终止,并且将不会发生对scanner的分配。控制最终会在某些处理程序中结束,但由于超出范围,因此无法参考scanner

因此,要回答你的问题:

如果错误确实得到投掷,并扫描对象得到封闭,或者我还是得做,当我处理异常?

如果FileNotFoundException由构造抛出,没有Scanner对象close() ...所以你不必关闭它。

但是,根据您编写代码的方式,您可能会到达处理程序或代码块,而无需知道是否抛出了异常,是否抛出构造函数或构造函数完成后抛出异常。处理这个问题的方式取决于您使用的Java版本。在Java 7之前,这个成语就像@ Sangeeth的答案。对于Java 7和更高版本,你可以这样写:

try (Scanner scanner = new Scanner(new File(path))) { 
    //your code here 
} catch (FileNotFoundException e) { 
    //log it 
} 

注意“尝试与 - 资源”的语法有一个隐含的finally是每个在的开始宣布(autocloseable)资源的自动调用close()try。这可以免除您对在各种可能的成功和失败情况下关闭资源的繁琐代码的责任。


事实上,我们可以把这个层面做得更深一层。 Scanner构造函数调用FileInputStream来打开该文件,这就是FileNotFoundException将被抛出的地方。反过来,这将通过调用本地open方法实际打开文件。如果在这个过程中出现问题(并抛出异常),那么在允许异常传播之前,构造者有责任确保释放任何资源(例如,本地流被关闭)。

它必须以这种方式工作,因为失败的构造函数不会返回任何东西,并且他们不能依赖更深层次的东西知道如何释放特定异常处理程序中的资源。

+0

+1 ..很好回答:) – TheLostMind 2014-10-29 18:05:56