Last active
January 25, 2024 08:52
-
-
Save giuliano-macedo/4d11d6b3bb003dba3a1b53f43d81b30d to your computer and use it in GitHub Desktop.
Download large files in rust with progress bar using reqwest, future_util and indicatif
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// you need this in your cargo.toml | |
// reqwest = { version = "0.11.3", features = ["stream"] } | |
// futures-util = "0.3.14" | |
// indicatif = "0.15.0" | |
use std::cmp::min; | |
use std::fs::File; | |
use std::io::Write; | |
use reqwest::Client; | |
use indicatif::{ProgressBar, ProgressStyle}; | |
use futures_util::StreamExt; | |
pub async fn download_file(client: &Client, url: &str, path: &str) -> Result<(), String> { | |
// Reqwest setup | |
let res = client | |
.get(url) | |
.send() | |
.await | |
.or(Err(format!("Failed to GET from '{}'", &url)))?; | |
let total_size = res | |
.content_length() | |
.ok_or(format!("Failed to get content length from '{}'", &url))?; | |
// Indicatif setup | |
let pb = ProgressBar::new(total_size); | |
pb.set_style(ProgressStyle::default_bar() | |
.template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})") | |
.progress_chars("#>-")); | |
pb.set_message(&format!("Downloading {}", url)); | |
// download chunks | |
let mut file = File::create(path).or(Err(format!("Failed to create file '{}'", path)))?; | |
let mut downloaded: u64 = 0; | |
let mut stream = res.bytes_stream(); | |
while let Some(item) = stream.next().await { | |
let chunk = item.or(Err(format!("Error while downloading file")))?; | |
file.write_all(&chunk) | |
.or(Err(format!("Error while writing to file")))?; | |
let new = min(downloaded + (chunk.len() as u64), total_size); | |
downloaded = new; | |
pb.set_position(new); | |
} | |
pb.finish_with_message(&format!("Downloaded {} to {}", url, path)); | |
return Ok(()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found this discussion by chance because I too wanted to download files easily using Tauri and Tauri Upload Plugin as now it also has a download function with a ProgressHandler which can download a file from a URL to a Disk
![image](https://user-images.githubusercontent.com/72456774/227211559-f8209c5e-d03d-4b66-a5c0-88b231fda72b.png)
Just in Case anyone stumbles here with the same problem.