gpt4 book ai didi

自动关闭资源的Java 8 Stream(基于资源).iterator()?

转载 作者:行者123 更新时间:2023-11-30 08:30:55 26 4
gpt4 key购买 nike

Java 8 Stream.iterator() 会在完成后自动关闭流吗?我想不是...

我有这样的东西:

class Provider implements Serializable {

Iterator<String> iterator() {
Stream<String> stream = new BufferedReader(...).lines();
return stream.iterator();
}
}

这个迭代器被一些不知道迭代器基于文件读取资源的其他类使用。也就是

class Consumer {
void f() {
Iterator<String> iterator = provider.iterator();
// code that calls iterator methods at non-determined times
}
}

我必须流式传输该文件,因为它太大而无法放入内存。但是我希望能够在迭代器没有更多元素时自动关闭资源,这样我就不会泄漏资源。 Provider 类是 Serializable 并且我不能将 Stream 或 BufferedReader 作为成员。

有什么好的方法吗?

最佳答案

首先,请注意您从 BufferedReader.lines 创建的流不包含任何资源,因此关闭流没有任何效果:

BufferedReader br = new BufferedReader(...);
try(Stream<String> stream = br.lines()) {
... use stream
}
// br is still open here!

如果流持有资源,通常会明确记录。例如,Files.lines记录这个:

The returned stream encapsulates a Reader. If timely disposal of file system resources is required, the try-with-resources construct should be used to ensure that the stream's close method is invoked after the stream operations are completed.

BufferedReader.lines中没有这样的备注文档。

因此,在您的情况下,如果 BufferedReader 确实包含需要关闭的资源,则您有责任关闭它。情况并非总是如此。例如,如果您创建 new BufferedReader(new StringReader(string)),您没有任何资源可以关闭,所以不调用 close() 方法。

不管怎样,回到你的问题。假设流中实际持有一个资源(例如从 Files.lines() 创建),如果你只是返回一个迭代器,它不会自动关闭,无论迭代器是否遍历到最后.如果您想在某个特定时刻关闭流,则必须显式调用流上的 close() 方法。否则你必须依赖垃圾收集器,它最终会将底层资源对象(例如 FileInputStream)放入最终化队列,最终调用该对象的 finalize 方法,该方法将关闭文件。您无法保证何时会发生这种情况。

另一种方法是将整个输入文件缓冲到内存中(假设它不是很长)并在返回迭代器之前关闭文件。您可以在没有任何流 API 的情况下读取文件:

return Files.readAllLines(pathToTheFile).iterator();

关于自动关闭资源的Java 8 Stream(基于资源).iterator()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40935029/

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