【问题标题】:How to return a Stream and close the underline source?如何返回 Stream 并关闭下划线源?
【发布时间】:2021-01-06 13:40:43
【问题描述】:

这是背景。我有一个操作可能会从 hbase 扫描很多行。因为行数可能很大,所以我想返回一个 Stream of rows。问题是:如何关闭 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。有什么优雅的方法吗?

【问题讨论】:

    标签: java stream hbase


    【解决方案1】:

    有办法。

    首先我们观察到Stream 实现了AutoCloseable。所以我们可以实现一个 Stream 包装器,在其 close() 方法中关闭 scanner 实例。

    您可以通过手动编写 Stream 包装类来实现这一点。该类只需将所有Stream API 调用委托给一个包装好的Stream 类。对于close(),还需要关闭ResultScanner资源。您可以使用包装类构造函数中的参数来提供它。

    它可能看起来像这样:

    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 可能能够为您生成一个骨架包装类以节省您的工作量。检查您的 IDE 的文档等)

    您也可以使用使用 java.lang.reflect.Proxy ... 或其他方式实现的动态代理来实现这一点。

    一旦你实现了包装类,你就可以包装并返回主流;例如

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

    为确保扫描器实际关闭,此方法的结果应在 try with resources 语句中分配给资源变量。

    但这并不优雅。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多