rust actix-web upload file

使用 actix-web上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

use tokio::fs::{create_dir_all, File};
use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
use futures_util::StreamExt as _; // for file payload.next()

//上传文件,可以上传多个文件,都是file字段
#[post("/upload")]
async fn upload(mut payload: Multipart) -> impl Responder {
//文件上传根目录
let base_path = "./assets/upload";

//创建根目录
if let Err(e) = create_dir_all(base_path).await {
return HttpResponse::Ok().body(format!("创建文件夹失败,请检查是否有权限! {}".to_string(),e));
}

//多个文件数组
let mut file_paths = Vec::new();

//其他参数 user_id
let mut user_id = String::new();

//其他参数 dept_id
let mut dept_id = String::new();

//遍历 payload 需要引入 use futures_util::StreamExt as _;
while let Some(Ok(mut field)) = payload.next().await {
// 获取字段信息
let content_disposition = field.content_disposition();
let field_name = content_disposition.get_name().unwrap();

//file为上传文件字段
if field_name == "file" {
// Handle file upload
let file_name = content_disposition.get_filename().unwrap_or("default_file");

//完整路径 base_path(根目录) + 要上传的文件
let file_path_local: String = format!("{}/{}", base_path, file_name);
file_paths.push(file_path_local.clone());

let mut file = File::create(file_path_local).await.unwrap();

while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
file.write_all(&data).await.unwrap();
}

//处理其他参数 userId
} else if field_name == "userId" {
while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
user_id.push_str(&String::from_utf8_lossy(&data));
}
//处理其他参数 deptId
} else if field_name == "deptId" {
while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
dept_id.push_str(&String::from_utf8_lossy(&data));
}
}
}

//file_paths 为路径数组

return HttpResponse::Ok().body("文件上传成功!".to_string());

}