当前位置: 首页 > 知识库问答 >
问题:

如何使用InputStreamand OutputStream以反应式方式读取和写入文件

谢宸
2023-03-14

我试图在操作中读取Excel文件,或向其中添加新数据并将其写回。我还试图用通量和Mono来完成一个完整的反应过程。其思想是通过webservice返回结果文件或bytearray。

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

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

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

例如,webservice部分如下所示。

@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不太一致。这里有一些指导会很好。我希望整个序列都是非阻塞的。

共有1个答案

毋澄邈
2023-03-14

不幸的是,WorkbookFactory。create()操作正在阻塞,因此必须使用命令式代码执行该操作。然而,获取每个timeKeepingEntry可以反应性地完成。您的代码如下所示:

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

这会将工作簿保存在内存中,但在请求通量元素时,会根据需要获取每个条目。

 类似资料:
  • 我试图使用spring webflux以一种被动的方式从类路径中读取文件。我能阅读文件。但是我不能解析成Foo对象。 我正在尝试以下方法,但不确定如何转换为FOO类。 帮助赞赏。

  • 问题内容: 请看下面的代码 我正在尝试读取CSV文件,在代码中编辑文本,然后将其写回到.txt文件中。我的问题是,我有葡萄牙语单词,因此应使用ANSI格式读写文件。现在,输出文件中的某些葡萄牙语单词已替换为符号。 如何在Java中以ANSI格式读取文本数据并将其写入文件? 问题答案: 要读取具有特定编码的文本文件,可以将FileInputStream结合使用InputStreamReader。Wi

  • 问题内容: 用例如下: 如果写入日志文件失败,则应回退相应的DB事务。 因此,应以事务处理方式执行写入文件的操作。 我选择了Apache Commons Transaction库。 还有一个问题,那就是我没有找到更合适的文档或示例,这让我无法走得更远。 我创建了FileResourceManager的实例: FileResourceManager frm = new FileResourceMan

  • 本文向大家介绍java读取文件和写入文件的方式(简单实例),包括了java读取文件和写入文件的方式(简单实例)的使用技巧和注意事项,需要的朋友参考一下 Java代码 Java代码 以上就是小编为大家带来的java读取文件和写入文件的方式(简单实例)全部内容了,希望大家多多支持呐喊教程~

  • 问题内容: 如何在不启动GUI的情况下如何编写python脚本来读取Tensorboard日志文件,提取损失和准确性以及其他数字数据? 问题答案: 您可以使用TensorBoard的Python类或脚本来提取数据: 如何从TensorBoard导出数据? 如果您想导出数据以在其他地方可视化(例如iPython Notebook),那也是可能的。您可以直接依赖TensorBoard用来加载数据的基础

  • 问题内容: 我正在尝试实现一个非常简单的用例,UI功能,其中: 有一个带有一些内容的标签 如果单击,则将文本输入替换为可用标签的内容 用户可以编辑内容 按下回车键时,输入将隐藏并且标签将返回具有更新内容的内容 我最终可以完全正确(实际上是使用MongoBD后端,redux等),而我唯一做不到的事情(花了一整天的时间在Google上搜索和阅读SOF类似的帖子)是: 当我的文字输入出现时,我无法将焦点