如何将Surf请求的响应体流式写入文件(避免内存全量加载)
使用Surf流式写入大文件到本地
Surf的Body实现了AsyncRead trait,借助异步IO工具就能实现边接收响应边写入文件,无需将整个文件加载到内存。具体实现步骤如下:
1. 确认依赖配置
确保Cargo.toml中包含所需依赖(需启用异步IO相关特性):
[dependencies] surf = "2.3" tempfile = "3.8" tokio = { version = "1.0", features = ["full"] } anyhow = "1.0"
2. 流式写入代码实现
使用tokio::io::copy异步复制响应体到文件,实现流式处理:
use anyhow::Context; use tokio::io; use tempfile::tempfile; #[tokio::main] async fn main() -> anyhow::Result<()> { let link = "https://example.com/large-file"; let mut response = surf::get(link) .await .map_err(|err| anyhow::anyhow!(err)) .context(format!("Failed to fetch from {}", link))?; let mut image_tempfile = tempfile()?; // 异步流式复制响应体到文件,全程不占满内存 io::copy(&mut response.body_mut(), &mut image_tempfile).await?; // 可选:若后续需要操作文件,将文件指针移回起始位置 image_tempfile.seek(std::io::SeekFrom::Start(0)).await?; Ok(()) }
核心说明
response.body_mut()获取到的Body是异步可读对象,tokio::io::copy会自动处理边读边写的逻辑,内存中只会保留一小段缓冲区数据。- 必须使用异步运行时(如tokio),因为Surf的网络请求和IO操作都是异步的。如果项目使用
async-std,替换为async_std::io::copy即可,原理一致。
内容的提问来源于stack exchange,提问作者Qwertie
相关产品推荐
相关产品推荐

