将 reqwest 的 bytes_stream 复制到 tokio 文件中。

6

我试图使用 reqwest 下载的文件并将其复制到 tokio 文件中。由于文件太大无法存储在内存中,因此需要通过 bytes_stream() 而不是 bytes() 进行处理。

我尝试了以下内容:

let mut tmp_file = tokio::fs::File::from(tempfile::tempfile()?);
let byte_stream = reqwest::get(&link).await?.bytes_stream();
tokio::io::copy(&mut byte_stream, &mut tmp_file).await?;

这个问题的失败是由于

    |
153 |     tokio::io::copy(&mut byte_stream, &mut tmp_file).await?;
    |     --------------- ^^^^^^^^^^^^^^^^ the trait `tokio::io::AsyncRead` is not implemented for `impl Stream<Item = Result<bytes::bytes::Bytes, reqwest::Error>>`
    |     |
    |     required by a bound introduced by this call

有没有办法在Stream上获得AsyncRead特性或以其他方式将数据复制到文件中? 我使用tokio文件的原因是稍后需要从中进行AsyncRead操作。也许将其复制到常规std :: File中,然后将其转换为tokio :: fs :: File会更有意义?


我认为你需要在你的数据流上调用 StreamExt::for_each,对每个数据包写入文件。 - Aleksander Krauze
1个回答

5

这种方法可行。它松散地基于 bytes_stream() 的示例。

注意: 在这里您可能想要缓冲写入

use futures::StreamExt;

let mut tmp_file = tokio::fs::File::from(tempfile::tempfile()?);
let mut byte_stream = reqwest::get(&link).await?.bytes_stream();

while let Some(item) = byte_stream.next().await {
  tokio::io::copy(&mut item?.as_ref(), &mut tmp_file).await?;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接