Working with Tarballs
Recipe | Crates | Categories |
---|---|---|
Decompress a tarball | ||
Compress a directory into a tarball | ||
Decompress a tarball while removing a prefix from the paths |
Decompress a tarball
Decompress (flate2::read::GzDecoder
⮳) and extract (tar::Archive::unpack
⮳) all files from a compressed tarball named archive.tar.gz
located in the current working directory to the same location.
use std::fs::File; use flate2::read::GzDecoder; use tar::Archive; pub fn main() -> Result<(), std::io::Error> { let path = "temp/archive.tar.gz"; let tar_gz = File::open(path)?; let tar = GzDecoder::new(tar_gz); let mut archive = Archive::new(tar); archive.unpack(".")?; Ok(()) }
Compress a directory into a tarball
Compress /var/log
directory into archive.tar.gz
.
Creates a std::fs::File
⮳ wrapped in flate2::write::GzEncoder
⮳ and tar::Builder
⮳
Adds contents of /var/log
directory recursively into the archive under backup/logs
path with tar::Builder::append_dir_all
⮳. flate2::write::GzEncoder
⮳ is responsible for transparently compressing the data prior to writing it into archive.tar.gz
.
use std::fs::create_dir; use std::fs::exists; use std::fs::File; use flate2::write::GzEncoder; use flate2::Compression; pub fn main() -> Result<(), std::io::Error> { // Create a temporary folder if !exists("temp")? { create_dir("temp")?; } // Create the archive file let tar_gz_file = File::create("temp/archive.tar.gz")?; // Create the compression encoder let enc = GzEncoder::new(tar_gz_file, Compression::default()); // Create a new archive builder with the underlying file as the // destination of all data written. let mut tar = tar::Builder::new(enc); // Archive the /var/log directory and all of its contents // (recursively), renaming it in the process tar.append_dir_all("temp/backup/var/log", "/var/log")?; Ok(()) }
Decompress a tarball while removing a prefix from the paths
Iterate over the tar::Archive::entries
⮳. Use std::path::Path::strip_prefix
⮳ to remove the specified path prefix (bundle/logs
). Finally, extract the tar::Entry
⮳ via tar::Entry::unpack
⮳.
use std::fs::File; use std::path::PathBuf; use anyhow::Result; use flate2::read::GzDecoder; use tar::Archive; pub fn main() -> Result<()> { let file = File::open("temp/archive.tar.gz")?; let mut archive = Archive::new(GzDecoder::new(file)); let prefix = "bundle/logs"; println!("Extracted the following files:"); archive .entries()? .filter_map(|e| e.ok()) .map(|mut entry| -> Result<PathBuf> { let path = entry.path()?.strip_prefix(prefix)?.to_owned(); entry.unpack(&path)?; Ok(path) }) .filter_map(|e| e.ok()) .for_each(|x| println!("> {}", x.display())); Ok(()) }
flate2
uses a pure-Rust implementation by default. Use feature flags to opt in to system zlib.