web*_*ter 5 java iterator java-8 java-stream
Java 8 完成后会Stream.iterator()
自动关闭流吗?我想不是...
我有这样的事情:
class Provider implements Serializable {
Iterator<String> iterator() {
Stream<String> stream = new BufferedReader(...).lines();
return stream.iterator();
}
}
Run Code Online (Sandbox Code Playgroud)
这个迭代器被其他一些不知道迭代器基于文件读取资源的类使用。那是
class Consumer {
void f() {
Iterator<String> iterator = provider.iterator();
// code that calls iterator methods at non-determined times
}
}
Run Code Online (Sandbox Code Playgroud)
我必须流式传输文件,因为它太大而无法放入内存。但是我希望能够在迭代器没有更多元素时自动关闭资源,这样我就不会泄漏资源。该Provider
班是Serializable
,我不能有任何的流或BufferedReader中的成员。
有没有好的方法可以做到这一点?
首先,请注意,您创建的流BufferedReader.lines
不包含任何资源,因此关闭流没有任何效果:
BufferedReader br = new BufferedReader(...);
try(Stream<String> stream = br.lines()) {
... use stream
}
// br is still open here!
Run Code Online (Sandbox Code Playgroud)
通常,如果流持有资源,则会明确记录。例如,Files.lines
记录以下内容:
返回的流封装了一个
Reader
. 如果需要及时处理文件系统资源,则应使用 try-with-resources 构造来确保在close
流操作完成后调用流的方法。
文档中没有这样的注释BufferedReader.lines
。
BufferedReader
因此,在您的情况下,如果它确实拥有需要关闭的资源,则您有责任关闭它。情况并非总是如此。例如,如果您 create new BufferedReader(new StringReader(string))
,则没有任何要关闭的资源,因此根本不调用该close()
方法也可以。
无论如何,回到你的问题。假设流实际上持有一个资源(例如,从 中创建Files.lines()
),如果您只是返回一个迭代器,则无论该迭代器是否遍历到末尾,它都不会自动关闭。close()
如果您想在某个特定时刻关闭流,则必须显式调用流上的方法。否则,您必须依赖垃圾收集器,它最终会将底层资源对象(例如FileInputStream
)放入终结队列中,最终将调用finalize
该对象的方法来关闭文件。您无法保证这种情况何时发生。
另一种方法是将整个输入文件缓冲到内存中(假设它不是很长)并在返回迭代器之前关闭文件。您可以在没有任何流 API 的情况下执行此操作来读取文件:
return Files.readAllLines(pathToTheFile).iterator();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1850 次 |
最近记录: |