尝试...在释放资源时最终进入内部?

时间:2013-01-04 11:17:44

标签: c# java programming-languages

我想将String写入Unicode文件。我在Java中的代码是:

public static boolean saveStringToFile(String fileName, String text) {
    BufferedWriter out = null;
    boolean result = true;
    try {
        File f = new File(fileName);
        out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(f), "UTF-8"));
        out.write(text);
        out.flush();
    } catch (Exception ex) {
        result = false;
    } finally {
        if (out != null)
            try {
                out.close();
            } catch (IOException e) {
                // nothing to do! couldn't close
            }
    }

    return result;
}

更新

现在将它与C#进行比较:

    private static bool SaveStringToFile(string fileName, string text)
    {
        using (StreamWriter writer = new StreamWriter(fileName))
        {
            writer.Write(text);
        }
    }

甚至try..catch形式将是:

    private static bool SaveStringToFile(string fileName, string text)
    {
        StreamWriter writer = new StreamWriter(fileName);
        try
        {
            writer.Write(text);
        }catch (Exception ex)
        {
            return false;
        }
        finally
        {
            if (writer != null)
                writer.Dispose();
        }
    }

也许是因为我来自C#和.Net世界。但这是将String写入文件的正确方法吗?这个简单的任务代码太多了。在C#中,我只想说out.close();就是这样但是在try..catch语句中添加finally似乎有点奇怪。无论发生什么,我都添加了finally语句来关闭文件(资源)。避免使用太多资源。这是Java中的正确方法吗?如果是这样,为什么close抛出异常?

8 个答案:

答案 0 :(得分:17)

你是正确的,你需要调用finally块中的close(),你还需要包装这是一个try / catch

通常,您将在项目中编写实用程序方法,或者使用像http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.Closeable)这样的库中的实用程序方法来关闭静态.i.e。忽略close()中的任何抛出异常。

另外需要注意的是,Java 7增加了对资源尝试的支持,无需手动关闭资源 - http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

答案 1 :(得分:3)

是的,在java中的finally()中尝试catch是没有什么奇怪的。 close()可能由于各种原因抛出IoException,这就是为什么它必须被try catch块包围。在最新的java SE 7 Try with resources

中,有一个改进的解决方案来解决你的这个问题

答案 2 :(得分:2)

与using语句等效的Java是Java 7中添加的try-with-resources语句:

public static void saveStringToFile(String fileName, String text) throws IOException {
    try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
        w.write(text);
    }
}

try-with-resources将自动关闭流(这意味着将其刷新),并在执行此操作时抛出任何异常。

如果您无论如何都要执行单次调用,则不需要BufferedWriter(其目的是将多次写入组合到基础流以减少系统调用次数,从而提高性能)。

如果你坚持通过返回false来处理错误,你可以添加一个catch子句:

public static boolean saveStringToFile(String fileName, String text) {
    try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
        w.write(text);
        return true;
    } catch (IOException e) {
        return false;
    }
}

答案 3 :(得分:1)

这应该可以解决问题。如果要管理具有复杂行为的异常,请创建StreamWriter

public static bool saveStringToFile(String fileName, String text) 
{
    try
    {
        File.WriteAllText(fileName, text, Encoding.UTF8);
    }
    catch (IOException exp)
    {
        return false;
    }
    return true;
}

答案 4 :(得分:0)

那么,问题是什么?没有正确或错误的方式。甚至可以关闭抛出IO异常?那你怎么办呢?我一般都喜欢不进行任何形式的重新抛弃。

问题是 - 你只是在关闭时吞下IO异常 - 好。你可以忍受那种吹吗?如果不是你有问题,如果是 - 没有错。

我从来没有这样做过,但是 - 再次,这取决于你的商业案例。

答案 5 :(得分:0)

arch = new File("path + name");
arch.createNewFile();
FileOutputStream fos = new FileOutputStream(arch);
fos.write("ur text");
fos.close();

我的方式。

答案 6 :(得分:0)

避免这种情况的最好方法是在out.flush()之后放置out.close(),如果关闭失败,将自动处理该进程。或者使用它更好(我正在使用):

File file = ...
   OutputStream out = null;
   try {
     out = new BufferedOutputStream(new FileOutputStream(file));
     ...
    finally {
     if (out != null) {
       out.close();
     }
   }
 }

答案 7 :(得分:0)

如果您想要最少的代码,可以使用FileUtils.writeStringToFile

FileUtils.writeStringToFile(new File(fileName), text);

我不会使用布尔值,因为它很少忽略发生错误的事实或它在异常消息中出现的原因。使用已检查的Exception可确保调用者始终正确处理此类错误,并可记录有意义的错误消息。

使用特定的CharSet保存文件

try {
    FileUtils.writeStringToFile(new File(fileName), text, "UTF-8");
} catch(IOException ioe) {
    Logger.getLogger(getClass()).log(Level.WARNING, "Failed to write to " + fileName, ioe);
}