Working with Tarballs

Decompress a tarball

flate2-badge tar-badge cat-compression-badge

Decompress (GzDecoder) and extract (Archive::unpack) all files from a compressed tarball named archive.tar.gz located in the current working directory to the same location.

# #[macro_use]
# extern crate error_chain;
extern crate flate2;
extern crate tar;

use std::fs::File;
use flate2::read::GzDecoder;
use tar::Archive;
#
# error_chain! {
#     foreign_links {
#         Io(std::io::Error);
#     }
# }

fn run() -> Result<()> {
    let path = "archive.tar.gz";

    let tar_gz = File::open(path)?;
    let tar = GzDecoder::new(tar_gz);
    let mut archive = Archive::new(tar);
    archive.unpack(".")?;

    Ok(())
}
#
# quick_main!(run);

Compress a directory into tarball

flate2-badge tar-badge cat-compression-badge

Compress /var/log directory into archive.tar.gz.

Creates a File wrapped in GzEncoder and tar::Builder.
Adds contents of /var/log directory recursively into the archive under backup/logspath with Builder::append_dir_all. GzEncoder is responsible for transparently compressing the data prior to writing it into archive.tar.gz.

# #[macro_use]
# extern crate error_chain;
extern crate tar;
extern crate flate2;
#
# error_chain! {
#     foreign_links {
#         Io(std::io::Error);
#     }
# }

use std::fs::File;
use flate2::Compression;
use flate2::write::GzEncoder;

fn run() -> Result<()> {
    let tar_gz = File::create("archive.tar.gz")?;
    let enc = GzEncoder::new(tar_gz, Compression::default());
    let mut tar = tar::Builder::new(enc);
    tar.append_dir_all("backup/logs", "/var/log")?;
    Ok(())
}
#
# quick_main!(run);

Decompress a tarball while removing a prefix from the paths

flate2-badge tar-badge cat-compression-badge

Iterate over the Archive::entries. Use Path::strip_prefix to remove the specified path prefix (bundle/logs). Finally, extract the tar::Entry via Entry::unpack.

# #[macro_use]
# extern crate error_chain;
extern crate flate2;
extern crate tar;
#
# error_chain! {
#     foreign_links {
#         Io(std::io::Error);
#         StripPrefixError(::std::path::StripPrefixError);
#     }
# }

use std::fs::File;
use std::path::PathBuf;
use flate2::read::GzDecoder;
use tar::Archive;

fn run() -> Result<()> {
    let file = File::open("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(())
}
#
# quick_main!(run);