尝试使用资源使用InputStreamReader将流包装在哪里? [英] try-with-resources where to wrap stream with InputStreamReader?

查看:30
本文介绍了尝试使用资源使用InputStreamReader将流包装在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能想多了,但我只是写了代码:

try (InputStream in = ModelCodeGenerator.class.getClassLoader().getResourceAsStream("/model.java.txt"))
{
    modelTemplate = new SimpleTemplate(CharStreams.toString(new InputStreamReader(in, "ascii")));
}

这意味着InputStreamReader永远不会关闭(但在本例中,我们知道它的Close方法只关闭基础InputStream。)

可以这样写:

try (InputStreamReader reader = new InputStreamReader(...))

但这似乎更糟糕。如果InputStreamReader出于某种原因抛出,InputStream将永远不会关闭,对吗?这是C++中调用其他构造函数的构造函数的常见问题。异常可能导致内存/资源泄漏。

这里有没有最佳实践?

推荐答案

这意味着InputStreamReader永远不会关闭

嗯?在您的代码中,它是...它当然也会处理您的资源流的.lose()。有关更多详细信息,请参阅下面的内容...

As @SotiriosDelimanolis mentions但是,您可以在try-with-resource语句的"resource块"中声明多个资源。

您现在有另一个问题:.getResourceAsStream()可以返回NULL;因此您可能有NPE。

如果我是你,我会这么做:

final URL url = ModelCodeGenerator.class.getClassLoader()
    .getResource("/model.java.txt");

if (url == null)
    throw new IOException("resource not found");

try (
    final InputStream in = url.openStream();
    final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
    // manipulate resources
}

有一个非常重要的问题需要考虑但是...

Closeable确实扩展了AutoCloseable;事实上,它的不同之处只是抛出的异常(IOExceptionvsException)。但行为有根本区别

来自AutoCloseable.close()的javadoc(重点是我的):

请注意,与Closeable的Close方法不同,此Close方法不要求是幂等的。换句话说,多次调用此Close方法可能会产生一些明显的副作用,这与Closeable.Close不同,Closeable.Close在多次调用时必须无效。但是,强烈建议此接口的实现者使他们的Close方法是幂等的。

确实,Closeable的javadoc对此很清楚:

关闭此流并释放与其关联的所有系统资源。如果流已经关闭,则调用此方法不会产生任何效果。

您有两点非常重要:

  • 根据合同,Closeable还负责与其关联的所有资源;因此,如果关闭包装了InputStreamReaderBufferedReader,则所有这三个资源都将关闭;
  • 如果您多次调用.close(),则不会有进一步的副作用。

当然,这也意味着您可以选择Paranid选项并保留对所有Closeable资源的引用,然后关闭它们;但是,如果您的混合中有AutoCloseable资源而不是Closeable

,请注意

这篇关于尝试使用资源使用InputStreamReader将流包装在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆