关闭流/套接字和try-catch-finally

Che*_*tah 5 java sockets io try-catch character-encoding

这是一个我有疑问的例子(来自另一个SO问题):

public static void writeToFile (final String filename)
{
    PrintWriter out = null;     
    FileOutputStream fos = null;

    try
    {
        fos = new FileOutputStream(filename);
        out = new PrintWriter(new BufferedWriter(
                              new OutputStreamWriter(fos, "UTF-8")));

        for (final String line : log)
        {
            out.println(line);
        }

        out.flush();
        out.close();
    }
    catch (final Exception e)
    {
        System.err.println("Unable to write log to file.");
    }
    finally
    {
        if (fos != null)
        {
            try
            {
                fos.close();
            }
            catch (final IOException e)
            {
                System.err.println("Unable to write log to file.");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我认为这段代码工作正常并释放所有资源应该等等.我的问题是:

  1. 我为什么要被关闭FileOutputStreamfinally的部分try-catch-finally?当然我可以把代码顺序放在try-catch?之后?

  2. 为什么我必须关闭FileOutputStream分开,而不是简单地更换new OutputStreamWriter(fos, ...使用new OutputStreamWriter(new FileOutputStream(filename), ...?如果我先关闭FileOutputStream,会自动关闭其余的并释放资源吗?同样的问题适用于套接字,如果我关闭套接字连接会自动关闭流读取器/编写器并释放资源吗?

  3. 我一再被告知要确保我使用"UTF-8"读取和写入流,因为不同的系统具有不同的字符集(或者沿着这些行的东西).这是否仍然适用于读取/写入RAW字节数据(例如,来自非文本文件或加密的结果),因为我认为charsets只与文本字符有关?

Viv*_*sse 6

  1. 因为如果你的代码抛出一个未处理的异常,try-catch块之后的代码片将永远不会被执行.NullPointerExcpetion例如,就是这种情况.

  2. 你不必.如果关闭流,则其关闭的任何流也将关闭.

  3. 不可以.只有在将字节转换为字符(或相反)时才是这种情况.您正在指定charset OutputStreamWriter,它负责将字符转换为字节.