在上一篇,我们写了一个只有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,如图:
![](https://img.haomeiwen.com/i5306629/8601bf068454f3ac.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);
}
网友评论