gpt4 book ai didi

java - try-with-resources 在哪里用 InputStreamReader 包装流?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:34:25 27 4
gpt4 key购买 nike

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

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

这意味着 InputStreamReader 永远不会关闭(但在这种情况下我们知道它的关闭方法只是关闭底层的 InputStream。)

可以这样写:

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

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

这里有最佳实践吗?

最佳答案

Which means the InputStreamReader is never closed

嗯?在你的代码中它是......它肯定也会处理你的资源流的 .close() 。有关更多详细信息,请参见下文...

As @SotiriosDelimanolis mentions但是,您可以在 try-with-resources 语句的“资源 block ”中声明多个资源。

这里还有一个问题:.getResourceAsStream() can return 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,是的;事实上,它只是“签名明智”的不同之处在于抛出的异常(IOException vs Exception)。但行为存在根本差异。

来自 AutoCloseable.close() 的 javadoc(强调我的):

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.

事实上,Closeable 的 javadoc 对此很清楚:

Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.

你有两个非常重要的观点:

  • 根据约定,Closeable 还负责处理与其关联的所有资源;所以,如果你关闭一个 BufferedReader,它包装了一个 Reader,而 Reader 包装了一个 InputStream,那么这三个都关闭了;
  • 如果您多次调用 .close(),则不会产生进一步的副作用。

当然,这也意味着您可以选择偏执选项并保留对所有 Closeable 资源的引用并将它们全部关闭;但是请注意,如果您将 AutoCloseable 资源混合到 Closeable 中!

关于java - try-with-resources 在哪里用 InputStreamReader 包装流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28074405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com