我认为您满足要求的唯一方法是向
Stream.onClose
方法假设您有以下类:
class CloseHandler implements Runnable {
List<Runnable> children = new ArrayList<>();
void add(Runnable ch) { children.add(ch); }
@Override
public void run() { children.forEach(Runnable::run); }
}
现在,您需要按如下方式使用流:
CloseHandler closeAll = new CloseHandler();
try (Stream<Something> stream = list.stream().onClose(closeAll)) {
// Now collect
stream.collect(Collectors.groupingBy(
this::extractFileName,
toFile(closeAll)));
}
这使用
try-with-resources
构造,以便在使用或发生错误时自动关闭流。请注意,我们正在通过
closeAll
靠近
流动一旦关闭
方法
下面是下游收集器的草图,它将收集/写入/发送元素到
Closeable
资源(请注意,我们还传递
全部关闭
关闭处理程序):
static Collector<Something, ?, Void> toFile(CloseHandler closeAll) {
class Acc {
SomeResource resource; // this is your closeable resource
Acc() {
try {
resource = new SomeResource(...); // create closeable resource
closeAll.add(this::close); // this::close is a Runnable
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
void add(Something elem) {
try {
// TODO write/send to closeable resource here
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
Acc merge(Acc another) {
// TODO left as an exercise
}
// This is the close handler for this particular closeable resource
private void close() {
try {
// Here we close our closeable resource
if (resource != null) resource.close();
} catch (IOException ignored) {
}
}
}
return Collector.of(Acc::new, Acc::add, Acc::merge, a -> null);
}
因此,它使用一个本地类(名为
Acc
)包装可关闭的资源,并将方法声明为
add
流的一个元素到可关闭的资源,也到
merge
二
Acc公司
实例,以防流是平行的(留作练习,以防值得付出努力)。
Collector.of
用于根据
Acc公司
类的方法,具有返回
null
,因为我们不想在
Collectors.groupingBy
。
最后,还有
close
方法,该方法在已创建包装的可关闭资源的情况下关闭该资源。
当流通过
尝试使用资源
构造,即
CloseHandler.run
方法将自动执行,这将依次执行之前添加的所有子关闭处理程序
Acc公司
实例已创建。