javaer学rust(三)

2022-09-19  本文已影响0人  yiang飞扬

在上一篇,我们写了一个只有main方法的demo,实现了下载网络文件的功能,但基于代码复用的思想,我们可以把下载的功能写成共用的方法,如下:

async fn downloadFile(file_url:&str)->String{
    let body = reqwest::get(file_url)
        .await
        .unwrap()
        .text()
        .await
        .unwrap();
    println!("body = {:?}", body);
    return body;
}

#[tokio::main]
async fn main() {
    let file_url="http://localhost:8234/group2/default/20220915/17/13/4/test.txt";
    downloadFile(file_url);
}

如果运行这个代码,会输出一些告警信息

warning: unused implementer of `Future` that must be used
  --> src\main.rs:16:5
   |
16 |     download_file(file_url);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_must_use)]` on by default
   = note: futures do nothing unless you `.await` or poll them

warning: `go-fastdfs-rust-client` (bin "go-fastdfs-rust-client") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target\debug\go-fastdfs-rust-client.exe`

Process finished with exit code 0

虽然有告警信息,代码其实是正常运行的,但奇怪的是download_file里面的信息并没有打印出来,如果加断点的话可以发现代码根本没执行到,为什么呢?问题其实出在异步方法上,因为方法是异步的,main方法没有被阻塞,download方法还没真正执行程序就结束了。那怎么解决呢,其实告警信息里面已经告诉解决方案了,那就是在异步方法后面加上await方法

async fn download_file(file_url:&str)->String{
    let body = reqwest::get(file_url)
        .await
        .unwrap()
        .text()
        .await
        .unwrap();
    return body;
}

#[tokio::main]
async fn main() {
    let file_url="http://localhost:8234/group2/default/20220915/17/13/4/test.txt";
    let body=download_file(file_url);
    println!("body = {:?}", body.await);
}

再次运行,就会发现没有告警信息了,而且文件内容也被打印出来了

因为后面我们还要做上传文件、删除文件等功能,因此我们可以考虑把相关功能都放到一个文件,对rust来说就是一个mod,类似于java的package,如图:


image.png

我们把上传文件的功能也加上

use std::borrow::Cow;

const UPLOAD_URL:&str ="http://localhost:8234/group2/upload";

pub async fn upload_file(file_path:&str)->String{
    let file_byte=std::fs::read(file_path).unwrap();
    // 一定要有file_name方法,且参数不能为空,否则数据上传失败
    let part=reqwest::multipart::Part::bytes(Cow::from(file_byte)).file_name("test.txt");
    let form = reqwest::multipart::Form::new().part("file",part);

    let response = reqwest::Client::new()
        .post(UPLOAD_URL)
        .multipart(form)
        .send()
        .await
        .unwrap();
    let url=response.text().await.unwrap();
    println!("{}",url);
    return url;


}

pub async fn download_file(file_url:&str)->String{
    let body = reqwest::get(file_url)
        .await
        .unwrap()
        .text()
        .await
        .unwrap();
    return body;
}

因为使用了multipart方式上传,在执行代码前需要把reqwest的multipart特性启用(rust的依赖和java的依赖有些不一样,java如果引用一个jar包的话,里面的所有功能都能用了,但rust需要你明确指出引用哪些功能),启用方式是修改cargo.toml文件,在features的属性上把multipart加上,如下:

[dependencies]
reqwest = { version = "0.11.11", features = ["json","multipart"] } 
#futures = "0.3" # for our Async / await blocks
tokio = { version = "1.12.0", features = ["full"] }

这时候如果在main方法中再调用download_file方法的话,就需要明确声明要使用哪个mod哪个方法了,类似于java的import,否则会提示找不到相应的方法

mod file_service;
use file_service::download_file;

#[tokio::main]
async fn main() {
    let file_url="http://localhost:8234/group2/default/20220915/17/13/4/test.txt";
    let body=download_file(file_url).await;
    println!("body = {:?}", body);
}
上一篇 下一篇

猜你喜欢

热点阅读