Rust中如何复制reqwest返回的bytes_stream以复用做两次PUT请求?
解决方案
当然可以只发起一次GET请求,不过不能直接复制bytes_stream——因为字节流是一次性的消费型对象,读取后就无法重复使用。正确的做法是先把GET响应的完整内容读到内存中,再基于这份内存数据生成两个可独立使用的请求体。
代码示例
use reqwest::Body; #[tokio::main] async fn main() { let client = reqwest::Client::new(); let get_url = "你的GET目标URL"; let upload_url_1 = "第一个PUT目标URL"; let upload_url_2 = "第二个PUT目标URL"; // 发起一次GET请求,把完整内容读到内存 let content_bytes = client.get(get_url).send().await.unwrap().bytes().await.unwrap(); // 基于内存中的字节数据生成两个独立的Body let body1 = Body::from(content_bytes.clone()); let body2 = Body::from(content_bytes); // 并发发起两个PUT请求(用tokio的join实现并发) let (res1, res2) = tokio::join!( client.put(upload_url_1).body(body1).send(), client.put(upload_url_2).body(body2).send() ); // 处理响应结果 let text1 = res1.unwrap().text().await.unwrap(); let text2 = res2.unwrap().text().await.unwrap(); println!("第一个PUT响应内容: {}", text1); println!("第二个PUT响应内容: {}", text2); }
关键说明
- 替换
bytes_stream()为bytes().await:直接将整个响应内容读取为Bytes类型,这是reqwest提供的可高效克隆、共享的字节缓冲区,内部基于引用计数实现,克隆操作几乎无额外内存开销。 - 生成独立请求体:通过克隆
Bytes得到两份可独立使用的实例,再分别包装成Body用于PUT请求。 - 并发执行:使用
tokio::join!让两个PUT请求同时执行,满足你提到的并发运行需求,比串行执行效率更高。
如果响应内容体积极大,担心内存占用过高,也可以考虑将内容写入本地临时文件,之后分别读取文件生成流,但这种方案复杂度更高,仅在超大文件场景下推荐使用。
内容的提问来源于stack exchange,提问作者Ryan Blignaut
相关产品推荐
相关产品推荐

