如何以被动方式使用InputStream和OutputStream

问题描述 投票:1回答:1

我正在尝试读取Excel文件以对其进行操作或向其中添加新数据并写回。我也正在尝试使用Flux和Mono完成一个完整的反应过程。想法是通过Web服务返回结果文件或字节数组。

我的问题是如何以非阻塞方式获取InputStream和OutputStream?

我正在使用Apache Poi库读取并生成Excel文件。

我目前有一个基于Mono.fromCallable()和阻塞代码来获取输入流的解决方案。

例如,Web服务部分如下。

@GetMapping(value = API_BASE_PATH + "/download", produces = "application/vnd.ms-excel")
public Mono<ByteArrayResource> download () {
    Flux<TimeKeepingEntry> createExcel = excelExport.createDocument(false);
    return createExcel.then(Mono.fromCallable(() -> {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        excelExport.getWb().write(outputStream);
        return new ByteArrayResource(outputStream.toByteArray());
    }).subscribeOn(Schedulers.elastic()));
}

以及文件的处理:

public Flux<TimeKeepingEntry> createDocument(boolean all) {
    Flux<TimeKeepingEntry> entries = null;
    try {
        InputStream inputStream = new ClassPathResource("Timesheet Template.xlsx").getInputStream();
        wb = WorkbookFactory.create(inputStream);
        Sheet sheet = wb.getSheetAt(0);

        log.info("Created document");

        if (all) {
            //all entries
        } else {
            entries = service.findByMonth(currentMonthName).log("Excel Export - retrievedMonths").sort(Comparator.comparing(TimeKeepingEntry::getDateOfMonth)).doOnNext(timeKeepingEntry-> {
                this.populateEntry(sheet, timeKeepingEntry);
            });
        }
    } catch (IOException e) {
        log.error("Error Importing File", e);
    }

    return entries;
}

此效果很好,但与Flux和Mono不太吻合。这里的一些指导会很好。我希望整个序列都不会阻塞。

spring-boot spring-webflux project-reactor
1个回答
0
投票

[不幸的是WorkbookFactory.create()操作被阻止,因此您必须使用命令式代码执行该操作。但是,每次都能获取KeepingEntry都是反应性的。您的代码如下所示:

public Flux<TimeKeepingEntry> createDocument() {
    return Flux.generate(
        this::getWorkbookSheet,
        (sheet, sink) -> {
            sink.next(getNextTimeKeepingEntryFrom(sheet));
        },
        this::closeWorkbook);
}

这会将工作簿保留在内存中,但是当请求Flux的元素时将按需获取每个条目。

© www.soinside.com 2019 - 2024. All rights reserved.