首页 > 解决方案 > 如何使用 tokio::io::BufReader 读取块

问题描述

我正在使用以下方法计算文件的校验和:

pub fn sha256_digest(file_path: &str) -> Result<String, Box<dyn Error>> {
    let file = fs::File::open(file_path)?;
    let mut reader = BufReader::new(file);
    let mut context = Context::new(&SHA256);

    loop {
        let consummed = {
            let buffer = reader.fill_buf()?;
            if buffer.is_empty() {
                break;
            }
            context.update(buffer);
            buffer.len()
        };
        reader.consume(consummed);
    }

    let digest = context.finish();

    Ok(write_hex_bytes(digest.as_ref()))
}

校验和:

dca3b9746da896f05072bdec6b788513029b26ab453b82e2e9d4365e56e2c913
Elapsed: 226.14ms

我已经用 tokio 试过了:

async fn sha256_digest(file_path: &str) -> Result<String, Box<dyn Error>> {
    let file = File::open(file_path).await?;
    let mut stream = FramedRead::new(file, BytesCodec::new());
    let mut context = Context::new(&SHA256);
    while let Some(bytes) = stream.try_next().await? {
        context.update(&bytes);
    }
    let digest = context.finish();
    Ok(write_hex_bytes(digest.as_ref()))
}

但不幸的是,计算校验和需要两倍的时间,因此我想尝试一个tokio::io::BufReader解决我遇到的问题的选项是实现Trait AsyncBufRead以便我可以使用消耗方法。

校验和:

dca3b9746da896f05072bdec6b788513029b26ab453b82e2e9d4365e56e2c913
Elapsed: 448.25ms

我在尝试:

async fn sha256_digest_BufReader(file_path: &str) -> Result<String, Box<dyn Error>> {
    let file = File::open(file_path).await?;
    let mut reader = BufReader::new(file);
    let mut context = Context::new(&SHA256);
    loop {
        let consummed = {
            let buffer = reader.buffer();
            if buffer.is_empty() {
                break;
            }
            context.update(buffer);
            buffer.len()
        };
        reader.consume(consummed);
    }
    let digest = context.finish();
    Ok(write_hex_bytes(digest.as_ref()))
}

但收到此错误:

error[E0599]: no method named `consume` found for struct `tokio::io::util::buf_reader::BufReader<tokio::fs::file::File>` in the current scope
  --> src/main.rs:63:16
   |
63 |         reader.consume(consummed);
   |                ^^^^^^^ method not found in `tokio::io::util::buf_reader::BufReader<tokio::fs::file::File>`

warning: unused import: `tokio::io::AsyncBufRead`

知道如何实施吗?

更新:我正在尝试这个:

async fn sha256_digest_BufReader(file_path: &str) -> Result<String, Box<dyn Error>> {
    let file = File::open(file_path).await?;
    let mut reader = BufReader::new(file);
    let mut context = Context::new(&SHA256);
    let mut buf: [u8; 8192] = [0; 8192]; //chunk size (8K, 65536, etc)

    while let Ok(size) = reader.read(&mut buf[..]).await {
        if size == 0 {
            break;
        }
        context.update(&buf[0..size]);
    }
    let digest = context.finish();
    Ok(write_hex_bytes(digest.as_ref()))
}

但仍然运行“慢”或至少两倍的时间,甚至改变块大小,例如使用65536,进行测试131072

标签: rustrust-tokio

解决方案


推荐阅读