首页 > 解决方案 > 从流“FramedRead”如何在每个块中“做某事”

问题描述

我想使用 crate indicatif 显示文件的上传进度,我正在使用reqwest异步上传文件,如下所示:

use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};

let file = File::open(file_path).await?;
let stream = FramedRead::new(file, BytesCodec::new());
let body = Body::wrap_stream(stream);
client.put(url).body(body)

进度条是这样实现的:

use indicatif::ProgressBar;

let bar = ProgressBar::new(1000);
for _ in 0..1000 {
    bar.inc(1);
    // ...
}
bar.finish();

如何从stream

let stream = FramedRead::new(file, BytesCodec::new());
// how on every chunk do X ? 
let body = Body::wrap_stream(stream);

我可以呼吁bar.inc(1)每一次互动吗?

从文档中我看到有一个read_buffer但是如何以一种我可以使用它来调用自定义函数的方式对其进行迭代,或者还计算在外壳中发送的字节数,例如,到目前为止我可以显示“发送的字节数”。

标签: rustrust-tokio

解决方案


例如,您可以使用TryStreamExt::inspect_ok,当使用该项目时,它将调用闭包并引用Ok(item)流中的每个。

use futures::stream::TryStreamExt;
use tokio_util::codec::{BytesCodec, FramedRead};

let stream = FramedRead::new(file, BytesCodec::new())
    .inspect_ok(|chunk| {
        // do X with chunk...
    });

let body = Body::wrap_stream(stream);

推荐阅读