首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用reqwest发布文件?

如何使用reqwest发布文件?
EN

Stack Overflow用户
提问于 2021-01-20 17:21:30
回答 3查看 4.8K关注 0票数 8

reqwest v0.9.18的文档展示了以下提交文件的示例:

代码语言:javascript
复制
let file = fs::File::open("from_a_file.txt")?;
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .body(file)
    .send()?;

reqwest v0.11的最新文档不再包含此示例,在调用body()时,试图构建它时会出现以下错误

代码语言:javascript
复制
the trait `From<std::fs::File>` is not implemented for `Body`

发送文件的更新方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-01-20 18:35:57

链接到的具体示例是在使用异步的板条箱之前。如果您想要使用这个确切的示例,那么您需要使用reqwest::Client而不是reqwest::blocking::Client。这还需要启用blocking特性。

为了明确起见,您仍然可以找到这个示例,它只是位于reqwest::blocking::RequestBuilderbody()方法的文档中。

代码语言:javascript
复制
// reqwest = { version = "0.11", features = ["blocking"] }
use reqwest::blocking::Client;
use std::fs::File;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let file = File::open("from_a_file.txt")?;

    let client = Client::new();
    let res = client.post("http://httpbin.org/post")
        .body(file)
        .send()?;

    Ok(())
}

还可以查看reqwestForm方法和RequestBuildermultipart()方法,例如,有一个file()方法。

如果您确实想使用异步,那么可以从FramedRead中使用板条箱。以及TryStreamExt特性,来自板条箱

只需确保为reqwest启用stream特性,为tokio-util启用codec功能。

代码语言:javascript
复制
// futures = "0.3"
use futures::stream::TryStreamExt;

// reqwest = { version = "0.11", features = ["stream"] }
use reqwest::{Body, Client};

// tokio = { version = "1.0", features = ["full"] }
use tokio::fs::File;

// tokio-util = { version = "0.6", features = ["codec"] }
use tokio_util::codec::{BytesCodec, FramedRead};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let file = File::open("from_a_file.txt").await?;

    let client = reqwest::Client::new();
    let res = client
        .post("http://httpbin.org/post")
        .body(file_to_body(file))
        .send()
        .await?;

    Ok(())
}

fn file_to_body(file: File) -> Body {
    let stream = FramedRead::new(file, BytesCodec::new());
    let body = Body::wrap_stream(stream);
    body
}
票数 16
EN

Stack Overflow用户

发布于 2022-07-02 11:47:15

如果您想使用multipart/form-data,并且您已经在使用Tokio,这种方法可以帮助您。

1.设置依赖项

代码语言:javascript
复制
# Cargo.toml

[dependencies]
tokio = { version = "1.19", features = ["macros", "rt-multi-thread"] }
reqwest = { version = "0.11.11", features = ["stream","multipart","json"] }
tokio-util = { version = "0.7.3", features = ["codec"] }

2.使用multipart/form-data上传文件

代码语言:javascript
复制
use reqwest::{multipart, Body, Client};
use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};

async fn reqwest_multipart_form(url: &str) -> anyhow::Result<String> {
    let client = Client::new();
    let file = File::open(".gitignore").await?;

    // read file body stream
    let stream = FramedRead::new(file, BytesCodec::new());
    let file_body = Body::wrap_stream(stream);

    //make form part of file
    let some_file = multipart::Part::stream(file_body)
        .file_name("gitignore.txt")
        .mime_str("text/plain")?;

    //create the multipart form
    let form = multipart::Form::new()
        .text("username", "seanmonstar")
        .text("password", "secret")
        .part("file", some_file);

    //send request
    let response = client.post(url).multipart(form).send().await?;
    let result = response.text().await?;

    Ok(result)
}

3.单元测试

代码语言:javascript
复制
#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_post_form_file() {
        let url = "http://httpbin.org/post?a=1&b=true";
        let get_json = reqwest_multipart_form(url).await.unwrap();

        println!("users: {:#?}", get_json);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-06-27 12:58:06

如果启用了特性流光,则机箱hyper可以为您完成此任务:

代码语言:javascript
复制
use hyper::{Body, Request}:
let file = File::open("from_a_file.txt").unwrap();
let mut streaming = Streamer::new(file)
// optional, set the field name
// streaming.meta.set_name("txt"); 
// optional, set the file name
streaming.meta.set_filename("from_a_file.txt");
// length sent as a chunk, the default is 64kB if not set
streaming.meta.set_buf_len(1024 * 1024); 

let body: Body = streaming.streaming();
// build a request 
let request: Request<Body> = Request::post("<uri-here>").body(body).expect("failed to build a request");

流线器将以1兆字节块的形式流文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65814450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档