Replace in-place compression

Compress gzip files to a temporary file first and then do an atomic
rename.
This commit is contained in:
KARASZI István 2021-01-07 16:50:13 +01:00
parent fa40c6e3d4
commit 956adfc90a
3 changed files with 12 additions and 2 deletions

1
Cargo.lock generated
View File

@ -1734,6 +1734,7 @@ dependencies = [
"tempfile", "tempfile",
"tokio", "tokio",
"ureq", "ureq",
"uuid",
"vergen", "vergen",
"walkdir", "walkdir",
"whoami", "whoami",

View File

@ -51,6 +51,7 @@ tar = "0.4.30"
tempfile = "3.1.0" tempfile = "3.1.0"
tokio = { version = "0.2", features = ["macros"] } tokio = { version = "0.2", features = ["macros"] }
ureq = { version = "2.0.0", features = ["tls"], default-features = false } ureq = { version = "2.0.0", features = ["tls"], default-features = false }
uuid = "0.8"
walkdir = "2.3.1" walkdir = "2.3.1"
whoami = "1.0.3" whoami = "1.0.3"

View File

@ -1,19 +1,27 @@
use flate2::Compression; use flate2::Compression;
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
use flate2::write::GzEncoder; use flate2::write::GzEncoder;
use std::fs::{create_dir_all, File}; use std::fs::{create_dir_all, rename, File};
use std::path::Path; use std::path::Path;
use tar::{Builder, Archive}; use tar::{Builder, Archive};
use uuid::Uuid;
use crate::error::Error; use crate::error::Error;
pub fn to_tar_gz(src: &Path, dest: &Path) -> Result<(), Error> { pub fn to_tar_gz(src: &Path, dest: &Path) -> Result<(), Error> {
let f = File::create(dest)?; let file_name = format!(".{}", Uuid::new_v4().to_urn());
let p = dest.with_file_name(file_name);
let tmp_dest = p.as_path();
let f = File::create(tmp_dest)?;
let gz_encoder = GzEncoder::new(f, Compression::default()); let gz_encoder = GzEncoder::new(f, Compression::default());
let mut tar_encoder = Builder::new(gz_encoder); let mut tar_encoder = Builder::new(gz_encoder);
tar_encoder.append_dir_all(".", src)?; tar_encoder.append_dir_all(".", src)?;
let gz_encoder = tar_encoder.into_inner()?; let gz_encoder = tar_encoder.into_inner()?;
gz_encoder.finish()?; gz_encoder.finish()?;
rename(tmp_dest, dest)?;
Ok(()) Ok(())
} }