如何返回流并关闭下划线源?

axzmvihb  于 2021-06-26  发布在  Java
关注(0)|答案(1)|浏览(379)

这是背景。我有一个操作可以从hbase扫描许多行。因为行的数量可能很大,所以我想返回一个行流。问题是:如何关闭resultscanner?
像这样的方法

public <T> Stream<T> getResultStream(String tableName,Scan scan, RowMapper<T> mapper){
        scan.setCaching(5000);//set number of rows to fetch for each rpc 
        Table table=this.getConnection().getTable(tableName);
        ResultScanner scanner = table.getScanner(scan);
        return StreamSupport.stream(scanner.spliterator(),false).map(mapper::mapRow);
        // scanner.close(); where to close it ?
    }

显然,我不能用这种方法关闭resultscanner。有什么优雅的方法吗?

gpfsuwkq

gpfsuwkq1#

有办法。
首先我们观察到 Stream 工具 AutoCloseable . 所以我们可以实现一个流 Package 器来关闭 scanner 示例在其 close() 方法。
您可以通过手工编写流 Package 器类来实现这一点。这个类只需要委托所有 Stream 对 Package 的 Stream 班级。如果是 close() ,它还需要关闭resultscanner资源。您可以使用 Package 类构造函数中的参数来提供。
它可能看起来像这样:

public class <T> MyStreamWrapper implements Stream<T> {

    private Stream<T> stream;
    private AutoCloseable resource;

    public MyStreamWrapper(Stream<T> stream, AutoCloseable resource) {
        this.stream = stream;
        this.resource = resource;
    }

    @Override
    public close() {
        this.stream.close();
        this.resource.close();
    }

    // methods to delegate all other Stream API methods to this.stream
}

(您的ide可能能够为您生成一个 backbone Package 器类,以节省您的工作量。查看ide文档等)
您也可以使用使用 java.lang.reflect.Proxy ... 或者其他方式。
一旦实现了 Package 器类,就可以 Package 并返回主流;例如

ResultScanner scanner = table.getScanner(scan);
    Stream<T> stream = 
         StreamSupport.stream(scanner.spliterator(), false)
                      .map(mapper::mapRow);
    return new MyStreamWrapper<>(stream, scanner);

为确保扫描程序实际关闭,应在try with resources语句中将此方法的结果分配给资源变量。
但它并不优雅。

相关问题