Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Download large files in rust with progress bar using reqwest, future_util and indicatif
// 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
.or(Err(format!("Failed to GET from '{}'", &url)))?;
let total_size = res
.ok_or(format!("Failed to get content length from '{}'", &url))?;
// Indicatif setup
let pb = ProgressBar::new(total_size);
.template("{msg}\n{} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})")
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) = {
let chunk = item.or(Err(format!("Error while downloading file")))?;
.or(Err(format!("Error while writing to file")))?;
let new = min(downloaded + (chunk.len() as u64), total_size);
downloaded = new;
pb.finish_with_message(&format!("Downloaded {} to {}", url, path));
return Ok(());
Copy link

mihaigalos commented Dec 8, 2021

@ozkanpakdil : have a look at the implementation of aim for how upload with a progress bar is handled.
I'm adding more features in the coming weeks/months.

Copy link

firasuke commented Jan 2, 2022

@giuliano-oliveira @mihaigalos can this be used to download multiple files concurrently?

Copy link

orhun commented Feb 4, 2022

You might want to consider using write_all instead of write:

Copy link

lennartkloock commented Feb 10, 2022

Yes, I agree. It is important to use write_all instead of write, otherwise it won't work

Copy link

giuliano-oliveira commented Feb 10, 2022

Makes perfect sense, thanks @orhun @lennartkloock

Copy link

Tails commented Jun 23, 2022

Does .get().send().await not immediately retrieve the whole response body to memory?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment