简体   繁体   English

如何修复 stream 错误:可能无法关闭 stream 错误

[英]How to fix stream error: may fail to close stream error

I am writing a method but see this error: may fail to close stream.我正在写一个方法,但看到这个错误:可能无法关闭 stream。 According to some solutions on different posts, I have added try and catch within the finally block.根据不同帖子上的一些解决方案,我在 finally 块中添加了 try 和 catch 。 I also added IOUtils.closeQuietly(fullObject, (Log) LOGGER).我还添加了 IOUtils.closeQuietly(fullObject, (Log) LOGGER)。 But it still doesn't work.但它仍然不起作用。 Anyone can help take a look?有谁能帮忙看看吗? Thanks!谢谢!

        S3Object fullObject = null;
        StringBuffer buffer = new StringBuffer();

        try {
            S3Object s3Response = s3Client.getObject(s3BucketName, s3Key);
            BufferedReader reader = new BufferedReader(new InputStreamReader(s3Response.getObjectContent()));
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
        } finally {
                if (fullObject != null) {
                    try {
                        fullObject.close();
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                    IOUtils.closeQuietly(fullObject, (Log) LOGGER);
                }
        }
        return buffer.toString();
    }

InputStreamReader implements AutoCloseable . InputStreamReader实现AutoCloseable This means that the intended use is try-with-resources :这意味着预期用途是try-with-resources

try (InputStreamReader reader = new InputStreamReader(s3Response.getObjectContent()) {
    ...
}

This should always close the stream irrespective of how the block exits (ie through normal completion, catch or finally clauses).这应该总是关闭 stream 而不管块如何退出(即通过正常完成、 catchfinally子句)。

The same is true for S3Object and BufferedReader . S3ObjectBufferedReader也是如此。 They can all be declared as resources within the same try block.它们都可以在同一个try块中声明为资源。

See https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html for more details.有关详细信息,请参阅https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

You should be using Java 7+ try with resources .您应该使用 Java 7+ 尝试资源 It will take care of closing the resources you declare in the list.它将负责关闭您在列表中声明的资源。 Any exceptions that may be thrown in the process of closing will be dealt with appropriately.在关闭过程中可能抛出的任何异常都会得到适当的处理。 (They are either allowed to propagate, or they are "suppressed" if an exception was already propagating.) (它们要么被允许传播,要么在异常已经传播时被“抑制”。)

Your code using try with resources would look like this.您使用资源尝试的代码如下所示。 It is half the length of the original version AND it won't have any resource leaks.它是原始版本的一半长度,并且不会有任何资源泄漏。 You "win" both ways.你“赢”了两种方式。

try (S3Object s3Response = s3Client.getObject(s3BucketName, s3Key);
     BufferedReader reader = new BufferedReader(
             new InputStreamReader(s3Response.getObjectContent()));
    ) 
{
    StringBuffer buffer = new StringBuffer();
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line);
    }
    return buffer.toString();
}

Notice that I have gotten rid of fullObject which your code wasn't using.请注意,我已经摆脱了您的代码未使用的fullObject

There are actually two managed resources in the above: the s3Response and the reader .上面实际上有两个托管资源: s3Responsereader It might not be strictly necessary to close both, but (IMO) closing them anyway is the correct thing to do... from the perspective of readability, if nothing else.关闭两者可能不是绝对必要的,但是(IMO)无论如何关闭它们是正确的做法......从可读性的角度来看,如果没有别的。

(It may also be possible to do the "read content as a string" more simply and/or more efficiently, but that is outside of the scope of this question.) (也可以更简单和/或更有效地执行“将内容作为字符串读取”,但这不在此问题的 scope 范围内。)

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM