tauri通过rust流式下载文件,并计算进度返回给前端
我通过Tauri前端中下载文件并展示进度事遇到了一些问题,通过a链接xhr下载总是有webview自带的下载提示,感觉很不友好,这里提供一个解决方案如下:
首先在main.rs 中定义一个全局变量(需要返回前端)
static mut GLOBAL_VARIABLE: String = String::new();
static mut GLOBAL_TOTAL: f64 = 0.0;
static mut ISDOWN: u64 = 0;
|
然后再通过tauri返回给前端这个下载函数
#[tauri::command] async fn download_file_q(url: String, path: String, puse: u64) -> Result<String, String> { unsafe { println!("ISDOWN:{}", ISDOWN); if ISDOWN >= 1 { return Err("Another file is currently downloading".into()); } } let client = reqwest::Client::new();
let mut file: File = OpenOptions::new() .read(true) .write(true) .create(true) .open(&path) .map_err(|e| e.to_string())?;
let file_len: u64 = file.metadata().map(|m: fs::Metadata| m.len()).unwrap_or(0);
let response_t = client.get(&url).send().await.map_err(|e| e.to_string())?; if response_t.status().is_success() { let total_size_t = response_t.content_length().unwrap_or(0) as f64; unsafe { GLOBAL_TOTAL = response_t.content_length().unwrap_or(0) as f64; }
let response: reqwest::Response = client .get(&url) .header("Range", format!("bytes={}-", file_len)) .send() .await .map_err(|e: reqwest::Error| e.to_string())?;
if response.status().is_success() { unsafe { let mut stream = response.bytes_stream();
file.seek(std::io::SeekFrom::End(0)) .map_err(|e| e.to_string())?;
while let Some(chunk) = stream.next().await { let bytes = chunk.map_err(|e: reqwest::Error| e.to_string())?;
file.write_all(&bytes) .map_err(|e: io::Error| e.to_string())?;
let file_len: u64 = file.metadata().map(|m: fs::Metadata| m.len()).unwrap_or(0); let progress: f64 = (file_len as f64 / total_size_t as f64) * 100.0; GLOBAL_VARIABLE = format!("{:.2}:{}:{}", progress, file_len, total_size_t); println!( "Download Progress: {:.2}% ({}/{} bytes)", progress, file_len, total_size_t );
if puse > 0 { tokio::task::yield_now().await; break; } else { }
if file_len as f64 >= total_size_t { ISDOWN = 0; GLOBAL_VARIABLE = String::new(); println!("ISDOWN-suceess:{}", ISDOWN); println!("下载完成"); } } } }
Ok("Download completed".into()) } else { unsafe { ISDOWN = 0; } Err("Download failed, response status is not success:1001".into()) } }
|
然后通过一个函数获取下载进度信息
#[tauri::command] fn glob() -> String { unsafe { format!("{}", GLOBAL_VARIABLE) } }
|