Skip to content

Instantly share code, notes, and snippets.

@raiguard
Last active November 20, 2021 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raiguard/365737daa9799fac326bbd8ccd4a57b0 to your computer and use it in GitHub Desktop.
Save raiguard/365737daa9799fac326bbd8ccd4a57b0 to your computer and use it in GitHub Desktop.
Synchronous file downloading
use anyhow::{anyhow, Result};
use std::cmp::min;
use std::fs::File;
use std::io::{Read, Write};
use indicatif::{ProgressBar, ProgressStyle};
use reqwest::blocking::Client;
pub fn download_file(client: &Client, url: &str, path: &str) -> Result<()> {
let mut res = client.get(url).send()?;
let total_size = res
.content_length()
.ok_or(anyhow!("Failed to get content length from '{}'", &url))?;
let pb = ProgressBar::new(total_size);
pb.set_style(ProgressStyle::default_bar()
.template("{msg}\n{spinner:.green} [{elapsed_precise}] [{bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})")
.progress_chars("=> "));
pb.set_message(&format!("Downloading {}", url));
let mut file = File::create(path)?;
let mut downloaded: u64 = 0;
let mut buf = vec![0; 8_096];
while downloaded < total_size {
// TODO: Handle interrupted error
let bytes = res.read(&mut buf)?;
file.write_all(&buf[0..bytes])?;
// Update progress bar
downloaded = min(downloaded + (bytes as u64), total_size);
pb.set_position(downloaded);
}
pb.finish_with_message(&format!("Downloaded {} to {}", url, path));
Ok(())
}
fn main() -> Result<()> {
download_file(
&Client::new(),
"https://releases.ubuntu.com/20.04/ubuntu-20.04.3-desktop-amd64.iso",
"ubuntu.iso",
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment