【问题标题】:How to read line by line from Spring Webflux FilePart DataBuffer如何从 Spring Webflux FilePart DataBuffer 中逐行读取
【发布时间】:2020-12-10 19:16:32
【问题描述】:

我正在使用 Spring Webflux 上传文件。就我而言,我必须上传一个 CSV 文件。 从我所做的搜索中可以收集到的是这段代码:

public Flux<String> getLines(Flux<FilePart> filePartFlux) {
    return filePartFlux.flatMap(filePart ->
            filePart.content().map(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);
                return new String(bytes, StandardCharsets.UTF_8);
            })
            .map(this::processAndGetLinesAsList)
            .flatMapIterable(Function.identity());
}

但在此过程中,如果 dataBuffer 达到其容量,它将部分读取最后一行,因此如果我传递半值,则会处理不正确的 csv。 有什么方法可以让我确定文件是逐行读取的,而不是 Flux。

示例: 从通量发出的数据缓冲区 1 包含:

<name,title,address
joe,engineer,straight way california,
mike,doc >

来自 Flux 的数据缓冲区 2 包含:

<tor,hatlway street,
jeremy,plumber,newyork>

我目前想到的解决方案是维护一个堆栈,我将通过比较 CSV 拆分的标头长度与拆分的当前记录长度来推送不完整的记录,如果它小于,则从堆栈中弹出 emelemt 并加入两个字符串。 我希望有一种有效的方法来完成这一切。

【问题讨论】:

    标签: java spring-webflux reactive


    【解决方案1】:
    filePartFlux is Flux<FilePart>
    
    val buffer = DataBufferUtils.join(filePartFlux).block()
    val reader =  buffer.asInputStream(true).bufferedReader()
    while(reader.ready()) {
        val line = reader.readLine()
        println("$line")
    }
    

    @Vishal jotshi,或者这样更好:

    DataBufferUtils.join(filePartFlux).subscribe { 
     buffer -> buffer.asInputStream(true).bufferedReader().use {
     reader -> while(reader.ready()) {
        val line = reader.readLine()
        println("$line")
    }
    

    }

    【讨论】:

    • 社区encourages 在代码旁边添加解释,而不是纯粹基于代码的答案。正如here 所解释的那样:“虽然此代码可能会回答问题,但提供有关 为什么 和/或 如何 此代码回答问题的附加上下文会提高其长期价值。 "
    • 阻塞和加入 filePartFlux 会将所有文件数据加载到内存中,这是我试图避免的。所以我不建议这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2014-12-22
    • 2017-07-07
    • 2014-01-15
    • 2011-04-12
    相关资源
    最近更新 更多