0

我需要删除程序中的文件。我的解决方案是有一种erase()方法可以做到这一点:

public static void erase(String string) {
    FileWriter fw = null;
    try {
        fw  = new FileWriter(string);
        fw.write(new String());
    } catch (IOException ie) {
        e.printStackTrace();
    } finally {
        fw.flush();
        fw.close(); 
    }
}

这里有几个问题:

  • 如果fw没有正确初始化(无论出于何种原因,丢失文件,无效权限等),那么当我尝试在finally块中关闭它时,就会出现 NullPointerException。

  • 如果我没有 finally 块,那么出于上述原因,我可能会抛出 NullPointerException。

  • 如果我关闭 try 块内的文件,那么如果文件正确打开但没有正确写入,我可能会泄漏资源。

我还忽略了哪些其他问题,如何强化这种方法?

4

3 回答 3

3

您可以将 finally 功能包装在 if 语句中:

if(fw != null){
    fw.close(); 
}

这将确保如果文件曾经被打开过,那么它将被关闭。如果一开始没有打开它,那么它不会做任何事情,这就是你想要的。

另外,我不确定它是否就像发布那样,但通常不建议只在 catch 块中打印堆栈跟踪并继续(“吞下”异常)。你真的应该让异常被抛出,因为这可能会隐藏错误并使跟踪它们变得非常困难。

编辑:见下面的评论。

于 2011-07-21T00:14:06.997 回答
1

包括flush()在你的主块中,并且只有close()在 catch 中。然后在关闭之前检查null:

finally {
    if(fw!=null) { fw.close(); }
    }

使用主块中的刷新,您还可以尝试/捕获close并记录或忽略任何错误:

finally {
    if(fw!=null) { 
        try { fw.close(); } catch(Throwable thr) { log.printError("Close failed: "+thr); thr.printStackTrace(); } 
        }
    }

或(通常不推荐):

finally {
    try { fw.close(); } catch(Throwable thr) {;}
    }

编辑

处理 I/O的最佳通用 Java 习惯用法 IMO 是:

FileWriter fw=null;
try {
    fw=new FileWriter(string);
    fw.write(new String());
    fw.close();
    fw=null;
    }
catch(IOException ie) {
    // do something real here to handle the exception, or don't catch it at all.
    } 
finally {
    if(fw!=null) { 
        try { fw.close(); } catch(Throwable thr) { thr.printStackTrace(); } // now we're really out of options
        }
    }    

这具有允许捕获和处理自身catch抛出的异常的重要作用。close()(仅当您可以以某种方式处理异常catch时才应出现该子句;不要捕获和忽略,通常您不应该简单地捕获和跟踪。)

于 2011-07-21T00:18:33.077 回答
1

据我所知,这是编写代码的正确惯用方式:

FileWriter fw = new FileWriter(string);
try {
    fw.write(new String());
    fw.flush();
} catch (IOException ie) {
    ie.printStackTrace();
} finally {
    fw.close(); 
}

解释:

  • 如果new FileWriter()抛出异常,那么我们不需要清理任何东西。该方法退出而不执行finally
  • 我们应该放入fw.flush(),而try不是放入finally。有两个原因:如果写入失败,那么我们不应该打扰刷新。此外,如果您将flush()in放入finally并引发异常,则将close()跳过。
于 2011-07-21T01:41:09.560 回答