简体   繁体   English

无法在“finally”子句中关闭() stream,未初始化的变量/未处理的 IOException [Java IO]

[英]Cannot close() stream in 'finally' clause, uninitialized variable/unhandled IOException [Java IO]

So I have this method in a class file just trying to write a Book object to aPath (string).所以我在 class 文件中有这个方法,只是试图将 Book object 写入 aPath(字符串)。 However, it gives me 'Unhandled IOException', which I am not sure I understand why as it seems I have a catch clause for my try block.但是,它给了我“未处理的 IOException”,我不确定我是否理解为什么我的 try 块似乎有一个 catch 子句。

So to fix this, I tried adding a 'throws' clause to my method, however once I did that, it said that the 'out' variable was not initialized.所以为了解决这个问题,我尝试在我的方法中添加一个“抛出”子句,但是一旦我这样做了,它就说“out”变量没有被初始化。

Is there any way I can close my stream inside the finally clause?有什么办法可以在 finally 子句中关闭我的 stream 吗?

    public void writeToFile(String aPath) {
    
        ObjectOutputStream out;
        try {
            out = new ObjectOutputStream(new FileOutputStream(aPath));
            
            out.writeObject(this.book);
        }
        catch(IOException e){
            System.out.println("Error writing to file");
            e.printStackTrace();
        }
        finally {
            out.close(); //unhandled IOException error :(
        }
    }

Using try with resources will handle the problem of uninitialized resources: 对资源使用 try将处理未初始化资源的问题:

public void writeToFile(String aPath) {
    try (ObjectOutputStream out = 
             new ObjectOutputStream(new FileOutputStream(aPath))) {
        out.writeObject(this.book);
    }
    catch (IOException e) {
        System.out.println("Error writing to file");
        e.printStackTrace();
    }
}

According to the JLS, an IOException thrown by the writeObject call, OR by the implicit close() of the resource will be caught in that handler.根据 JLS, writeObject调用或资源的隐式close()引发的IOException将在该处理程序中捕获。

It is so elegant...它是如此优雅...


Regarding, your attempt:关于,您的尝试:

I want to know why I cannot use out.close() in finally clause.我想知道为什么我不能在 finally 子句中使用 out.close() 。

Because out has not necessarily been initialized.因为out不一定已经初始化。 For example, if the IOException was thrown in new FileOutputStream(...) , out won't have been initialized.例如,如果在new FileOutputStream(...)中抛出了IOException ,则out不会被初始化。 To get it to work using an explicit finally , you would need to do something like this:要使用显式finally使其工作,您需要执行以下操作:

public void writeToFile(String aPath) {
    ObjectOutputStream out = null;
    try {
        out = new ObjectOutputStream(new FileOutputStream(aPath));
        out.writeObject(this.book);
    }
    catch (IOException e) {
        System.out.println("Error opening or writing to file");
        e.printStackTrace();
    }
    finally {
        if (out != null) {
            try {
                out.close();
            }
            catch (IOException e) {
                System.out.println("Error closing file");
                e.printStackTrace();
            }
        }
    }
}

Since you asked.... the exception handling / squashing is probably a bad idea:既然你问了......异常处理/挤压可能是一个坏主意:

  • The caller gets no indication file write has failed.调用者没有得到指示文件写入失败。 It will continue executing as if nothing happened.它将继续执行,就好像什么都没发生一样。

  • A stacktrace should not normally be written to stdout.通常不应将堆栈跟踪写入标准输出。 If it is relevant, the stacktrace should be logged:如果相关,则应记录堆栈跟踪:

    • If this is an end-user application, showing stacktraces to users is nasty.如果这是一个最终用户应用程序,向用户显示堆栈跟踪是令人讨厌的。 What they need is an informative error message.他们需要的是信息丰富的错误消息。 Separately logging the exception / stacktrace to a log file may be useful for the sysadmin who installed / configured the software, or the programmer who wrote it.将异常/堆栈跟踪单独记录到日志文件可能对安装/配置软件的系统管理员或编写它的程序员有用。
    • If this is a service, then stuff written to standard output may be lost.如果这是一项服务,那么写入标准 output 的内容可能会丢失。 Real errors should be logged.应该记录真正的错误。 Things that are (maybe) due to bad user input should (maybe) not be logged. (可能)由于用户输入错误而导致的事情(可能)不应该被记录下来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java关闭IOStream,最终出现错误:未处理的异常:java.io.IOException - Java Closing an IOStream in finally giving error: Unhandled Exception: java.io.IOException Java未初始化的变量,最终带来好奇心 - Java uninitialized variable with finally curiosity 声纳使用try-with-resources或在java8流的“ finally”子句中关闭此“ Stream” - Sonar-Use try-with-resources or close this “Stream” in a “finally” clause java8 stream 未处理的异常java.io.iOException - Unhandled Exception java.io.iOException java尝试finally块来关闭流 - java try finally block to close stream java.io.IOException:意外的流结束 - java.io.IOException: unexpected end of stream Java List.stream.forEach Lambda表达式内部未处理的IOException - Unhandled IOException Inside Java List.stream.forEach Lambda Expression java.io.IOException - IO流读取结束 - java.io.IOException - End of IO Stream Read Java-SonarLint检测阻止程序-在“ finally”子句中关闭此“ PreparedStatement” - Java - SonarLint Detect the Blocker - Close this “PreparedStatement” in a “finally” clause 无法运行程序java.io.IOException - Cannot run program java.io.IOException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM