单文件和多文件html的区别就是multiple
toml
[dependencies]
rocket = "0.5.1"
[package.metadata.rocket]
config = "Rocket.toml"
Rocket.toml 配置文件上传的大小限制
# Rocket.toml[default.limits]
form = "160MB" # 设置文件上传的最大大小为16MB
data-form = "160MB"
file = "160MB"
[development.limits]
form = "160MB" # 设置文件上传的最大大小为16MB
data-form = "160MB"
file = "160MB"[production.limits]
form = "160MB" # 设置文件上传的最大大小为16MB
data-form = "160MB"
file = "160MB"
html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>File Upload</title>
</head>
<body>
<h1>Upload a File</h1>
<!-- 表单的 action 指向你的 Rocket 应用的 '/upload' 路由 -->
<!-- 表单的 enctype 设置为 "multipart/form-data" 以支持文件上传 -->
<form action="http://127.0.0.1:8000/upload" method="post" enctype="multipart/form-data"><!-- 文件输入字段 --><!-- 单文件不需要multiple --><input type="file" name="file" id="file" multiple><br><br><!-- 提交按钮 --><input type="submit" value="Upload File">
</form>
</body>
</html>
单文件rs
use rocket::{routes,post,fs::TempFile,form::FromForm,form::Form,http::Status,
};
use std::path::{Path};#[derive(FromForm)]
struct Upload<'f> {file: TempFile<'f>,
}#[post("/", format = "multipart/form-data", data = "<form>")]
async fn upload_file(mut form: Form<Upload<'_>>) -> Result<String, Status> {// 直接从 Option<FileName> 中提取文件名并转换为 String,但是这种是没有后缀的,被优化过的// let file_name = match form.file.name() {// Some(s) => s,// None => "None-0" //可以用uuid// };// // 从 Path 中提取文件名,包括后缀名// let file_path = form.file.path().ok_or(Status::InternalServerError)?;// let path = Path::new(file_path); // 将路径转换为 Path 类型// let file_name1 = path.file_name().ok_or(Status::InternalServerError)?.to_str().ok_or(Status::InternalServerError)?.to_string();// println!("File name with extension: {}", file_name1); // 打印完整的临时文件名//取出上传的时候的老的文件名let file_name = form.file.raw_name().map(|name| name.dangerous_unsafe_unsanitized_raw().as_str()).unwrap_or_else(|| "default_filename.pdf"); // 如果没有文件名,则使用默认值println!("{}", file_name);//获取是json jpg png zip 。。。。。//let extension = form.file.content_type().map(|s| s.media_type().sub().to_string());//println!("{:?}", extension);//打印tmp_path目录let tmp_path = Path::to_str(form.file.path().unwrap()).map(|s| s.to_string()).unwrap();println!("{}", tmp_path);// 确保上传目录存在let upload_dir = "uploads"; // 你可以根据需要修改这个路径std::fs::create_dir_all(upload_dir).map_err(|_| Status::InternalServerError)?;// 尝试将文件保存到服务器let upload_path = std::path::Path::new(upload_dir).join(file_name); // 使用 join 方法将目录和文件名组合成 Pathif form.file.copy_to(upload_path.clone()).await.is_ok() {// 文件上传成功后的逻辑//删除临时目录的文件std::fs::remove_file(tmp_path).map_err(|_| Status::InternalServerError)?;Ok(format!("上传成功 {}", upload_path.display()))} else {Err(Status::InternalServerError)}
}#[rocket::main]
async fn main() -> Result<(), rocket::Error> {rocket::build().mount("/upload", routes![upload_file]).launch().await?;Ok(())
}
多文件
use rocket::{routes,post,fs::TempFile,form::FromForm,form::Form,http::Status,
};
use std::path::{Path};#[derive(FromForm)]
struct Upload<'f> {file: Vec<TempFile<'f>>,
}#[post("/", format = "multipart/form-data", data = "<form>")]
async fn upload_file(mut form: Form<Upload<'_>>) -> Result<String, Status> {let upload_dir = "uploads";std::fs::create_dir_all(upload_dir).map_err(|_| Status::InternalServerError)?;// 遍历 form.files 并使用 iter_mut 获取每个文件的可变引用for temp_file in form.file.iter_mut() {// 取出上传时的原始文件名let file_name = temp_file.raw_name().map(|name| name.dangerous_unsafe_unsanitized_raw().as_str()).unwrap_or_else(|| "default_filename.pdf"); // 如果没有文件名,则使用默认值println!("{}", file_name);let upload_path = Path::new(upload_dir).join(file_name.to_string());let tmp_path = Path::to_str(temp_file.path().unwrap()).map(|s| s.to_string()).unwrap();println!("{}", tmp_path);// 尝试将文件保存到服务器if !temp_file.copy_to(upload_path.clone()).await.is_ok() {std::fs::remove_file(tmp_path).map_err(|_| Status::InternalServerError)?;return Err(Status::InternalServerError);}}Ok(format!("上传成功"))
}#[rocket::main]
async fn main() -> Result<(), rocket::Error> {rocket::build().mount("/upload", routes![upload_file]).launch().await?;Ok(())
}