Closed januwA closed 2 years ago
@januwA 你好,请提供具体的错误信息。
我看了下 actix-web
的文档,估计这里的 chunk
类型是 bytes::Bytes
类型,如果是这样的话,可以调用 futures::io::Cursor
为其实现 AsyncRead
,这样就可以提供给 async_upload_reader
方法了,然后注意这个方法是 async
的所以要跟 await
。
@bachue 错误信息正如你说的那样,我不清楚怎么将bytes
传递给async_upload_reader
我现在将文件保存在本地,然后使用 async_upload_path
上传后在删除本地图片
#[post("upload_qn")]
pub async fn upload_qn(mut payload: Multipart) -> HttpResult {
let access_key = "-";
let secret_key = "-";
let bucket_name = "-";
let save_dir = "./public/qn/";
while let Some(mut field) = payload.try_next().await? {
let field_name = field.name();
if field_name == "file" {
let content_disposition = field.content_disposition();
let filename = content_disposition
.get_filename()
.map_or_else(|| Uuid::new_v4().to_string(), sanitize_filename::sanitize);
let filename = format!("{}_{}", Uuid::new_v4().to_string(), &filename);
let filepath = format!("{}{}", save_dir, &filename);
tokio::fs::create_dir_all(&save_dir).await?;
let mut f = tokio::fs::File::create(&filepath).await?;
while let Some(chunk) = field.try_next().await? {
f.write_all(&chunk).await?;
}
let credential = Credential::new(access_key, secret_key);
let upload_manager =
UploadManager::builder(UploadTokenSigner::new_credential_provider(
credential,
bucket_name,
Duration::from_secs(3600),
))
.build();
let uploader: AutoUploader = upload_manager.auto_uploader();
let params = AutoUploaderObjectParams::builder()
.object_name(&filename)
.file_name(&filename)
.build();
uploader
.async_upload_path(&filepath, params)
.await
.map_err(|e| OkError::e_s(e.to_string()))?;
// 上传后删除文件
tokio::fs::remove_file(&filepath).await?;
return res_ok!("");
}
}
Err(OkError::actix("上传失败"))
}
@januwA 看了下,有点麻烦,本来 Field
可以转变成 AsyncRead
的,但是偏偏 Field
内部用的是 Rc
导致它既不是 Sync
也不是 Send
的,导致就没法送进 async_upload_reader
了,我们这边因为内部实现的原因,强制要求 Reader
要实现 AsyncRead + Unpin + Debug + Send + Sync + 'static
的
@januwA 你这边用的 Multipart 库能替换成其他的吗?
@bachue 你好,现在我使用的是actix_multipart
,我还不清楚其它Multipart 库怎么在actix-web中使用
@januwA 一下子也想不到什么更好的方法,actix-web
好像也官方支持 actix_multipart
。目前可能可以的方式是用 tokio 的 tokio::sync::mpsc::channel
库,让 actix_multipart
向 Sender
发数据,然后将 Receiver
封装成 AsyncRead
的实现。
@bachue 嗯
你好,我正在 actix-web4 中将图片上传到七牛云,但是我不知道怎么将字节发送到七牛云,能帮帮我吗。
这是我的代码