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

问题描述

我正在编写一个方法,但看到此错误:可能无法关闭流。 根据不同帖子上的一些解决方案,我在 finally 块中添加了 try 和 catch。我还添加IoUtils.closeQuietly(fullObject,(Log) LOGGER)。但它仍然不起作用。有谁可以帮忙看看吗?谢谢!

        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 实现 AutoCloseable。这意味着预期用途是 try-with-resources:

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

无论块如何退出(即通过正常完成、catchfinally 子句),这都应始终关闭流。

S3ObjectBufferedReader 也是如此。它们都可以在同一个 try 块中声明为资源。

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

,

您应该使用 Java 7+ try with resources。它将负责关闭您在列表中声明的资源。关闭过程中可能抛出的任何异常都会得到适当的处理。 (如果异常已经在传播,它们要么被允许传播,要么被“抑制”。)

您使用尝试资源的代码如下所示。它是原始版本的一半长度,并且不会有任何资源泄漏。你“双赢”。

const arr = [
  {
    rooms: ['f03e6e40-870d-11eb-88a2-0149a30c02c5'],itemType: 'Item',id: '8c6a6070-80c0-11eb-9753-bb149505e85f',itemName: 'Item 1',},{
    rooms: ['eef60fc0-870d-11eb-88a2-0149a30c02c5'],id: '3aede320-870f-11eb-9e58-9d6fb0d8b5a8',itemName: 'Item 2',{
    rooms: ['f03e6e40-870d-11eb-88a2-0149a30c02c5'],id: '3ad52b00-870f-11eb-8f84-0782ebd81006',itemName: 'Item3',{
    itemType: 'Room',id: 'f03e6e40-870d-11eb-88a2-0149a30c02c5',itemName: 'Bedroom',id: 'eef60fc0-870d-11eb-88a2-0149a30c02c5',itemName: 'Bedroom 2',]

const result = arr.map((element) => {
  if (element.itemType !== 'Room') {
    return element
  }
  return {
    ...element,count: arr.filter(
      (i) => i.itemType === 'Item' && i.rooms.includes(element.id)
    ).length,}
})

console.log(result)

请注意,我已经删除了您的代码未使用的 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(); }

上面实际上有两个托管资源:fullObjects3Response。关闭它们可能不是绝对必要的,但是 (IMO) 无论如何关闭它们是正确的做法......从可读性的角度来看,如果没有别的。

(也可以更简单和/或更有效地执行“将内容作为字符串读取”,但这超出了本问题的范围。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...