tauri项目添加多文件下载功能,并支持下载进度回调显示在前端页面上
本文介绍了一个基于Rust和Tauri框架实现的多文件下载系统。该系统支持同时下载多个文件,允许用户自定义保存目录,并实时显示下载进度。Rust后端通过download_file函数处理下载任务,使用emit事件将进度发送给前端,前端监听download_progress事件更新界面。下载路径可指定或默认保存到下载文件夹,每个文件通过唯一ID标识以区分进度。项目已开源,完整代码可在GitHub仓库
·
支持多文件同时下载,以及选中下载目录,并且支持下载进度回显在界面上,下载是在rust端实现的,通过emit事件来将下载进度发送给前端,前端通过listen监听下载进度的事件,然后通过传递下载进度的消息,区分每一个文件的下载进度,再显示到界面上
rust端多文件下载
通过定义一个download_file下载函数,然后传递进来下载url,保存的路径,以及文件id,保存路径可以为空字符串,这样的话,就会默认保存到电脑的下载文件夹中,file_id是文件标识,可以是id或者文件名等,要保证唯一,因为是通过这个id来回调下载进度事件通知的
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct DownloadProgress {
file_id: String,
downloaded: u64,
total: u64,
}
#[tauri::command]
pub async fn download_file(
app: AppHandle,
url: String,
save_path: String,
file_id: String,
) -> Result<(), String> {
let client = Client::new();
let resp = client.get(&url).send().await.map_err(|e| e.to_string())?;
// if save path is empty
let mut save_path = save_path;
let file_name = url.split('/').last().unwrap();
if save_path.is_empty() {
let file_path = app
.path()
.resolve(file_name, BaseDirectory::Download)
.expect("failed to resolve resource");
save_path = file_path.to_str().unwrap().to_string();
}
let total_size = resp.content_length();
let mut stream = resp.bytes_stream();
let mut file = File::create(&save_path).map_err(|e| e.to_string())?;
let mut downloaded: u64 = 0;
while let Some(chunk) = stream.next().await {
let chunk = chunk.map_err(|e| e.to_string())?;
file.write_all(&chunk).map_err(|e| e.to_string())?;
downloaded += chunk.len() as u64;
app.emit(
"download_progress",
DownloadProgress {
file_id: file_id.clone(),
downloaded,
total: total_size.unwrap_or(0),
},
)
.unwrap();
}
Ok(())
}
前端调用下载
通过invoke来触发一个下载事件
await invoke('download_file', {
url,
savePath,
fileId,
})
然后通过监听download_progress事件,拿到下载进度的消息:
const downloadProgress = ref(0)
listen('download_progress', (event: any) => {
console.log(`downloading fileId--- ${event.payload.fileId}`)
console.log(`downloading downloaded--- ${event.payload.downloaded}`)
console.log(`downloading total--- ${event.payload.total}`)
downloadProgress.value = Number(
((event.payload.downloaded / event.payload.total) * 100).toFixed(2)
)
})
完整项目代码可以在我的开源项目中查看:
更多推荐
所有评论(0)