带Java Reactor的TarArchiveInputStream

带Java Reactor的TarArchiveInputStream,java,reactor,Java,Reactor,目前,我正在处理一个TarArchiveInputStream,如下所示: private Mono<Employee> createEmployeeFromArchiveFile() { return Mono.fromCallable(() -> { return new Employee(); }) .flatMap(employee -> { try { TarArchiveInp

目前,我正在处理一个TarArchiveInputStream,如下所示:

private Mono<Employee> createEmployeeFromArchiveFile() {

    return Mono.fromCallable(() -> {
        return new Employee();
    })
    .flatMap(employee -> {

        try {
            TarArchiveInputStream tar =
                    new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(new File("/tmp/myarchive.tar.gz"))));
            TarArchiveEntry entry;
            tar.read();
            while ((entry = tar.getNextTarEntry()) != null) {
                if (entry.getName().equals("data1.txt")) {
                    // process data
                    String data1 = IOUtils.toString(tar, String.valueOf(StandardCharsets.UTF_8));
                    if (data1.contains("age")) {
                        employee.setAge(4);
                    } else {
                        return Mono.error(new Exception("Missing age"));
                    }
                }
                if (entry.getName().equals("data2.txt")) {
                    // a lot more processing => put that in another function for clarity purpose
                    String data2 = IOUtils.toString(tar, String.valueOf(StandardCharsets.UTF_8));
                    employee = muchProcessing(employee, data2);
                }
            }
            tar.close();
        } catch (Exception e) {
            return Mono.error(new Exception("Error while streaming archive"));
        }

        return Mono.just(employee);
    });

}

private Employee muchProcessing(Employee employee, String data2) {
    if (data2.contains("name")) {
        employee.setName(4);
    } else {
        // return an error ?
    }
    return employee;
}
private Mono createEmployeeFromArchiveFile(){
返回Mono.fromCallable(()->{
返回新员工();
})
.flatMap(员工->{
试一试{
塔拉契维输入流焦油=
新的TarArchiveInputStream(新的GzipCompressorInputStream(新的FileInputStream(新文件(“/tmp/myarchive.tar.gz”)));
塔拉奇入口入口;
tar.read();
while((entry=tar.getNextTarEntry())!=null){
if(entry.getName().equals(“data1.txt”)){
//过程数据
stringdata1=IOUtils.toString(tar,String.valueOf(StandardCharsets.UTF_8));
如果(数据1.包含(“年龄”)){
员工设置(4);
}否则{
返回Mono.error(新异常(“缺少年龄”);
}
}
if(entry.getName().equals(“data2.txt”)){
//更多处理=>为了清晰起见,将其放在另一个函数中
stringdata2=IOUtils.toString(tar,String.valueOf(StandardCharsets.UTF_8));
employee=muchProcessing(employee,data2);
}
}
tar.close();
}捕获(例外e){
返回Mono.error(新异常(“流存档时出错”);
}
返回Mono.just(员工);
});
}
私有雇员多处理(雇员雇员,字符串数据2){
如果(数据2.包含(“名称”)){
雇员姓名(4);
}否则{
//返回一个错误?
}
返回员工;
}
首先,这是使用Reactor处理归档文件的正确方法吗?它工作得很好,但看起来像是平面图中的同步业务。我还没有找到更好的办法

其次,我不知道如何处理函数
muchProcessing(tar)
。如果该函数触发错误,它将如何返回这些错误,以便作为
Mono.error
正确处理?因为我想让这个函数返回我一个雇员


谢谢

您可以将
flatMap
中的任务作为
CompletableFuture
处理,并将其转换为
Mono
。这里有一个关于如何做到这一点的链接:

然后,您可以将其抽象为:

.flatMap(this::processEmployee).doOnError(this::logError).onErrorResume(getFallbackEmployee())