Working with Tarballs
Recipe | Crates | Categories |
---|---|---|
Compress a Directory into a Tarball | ||
Decompress 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> {
// Define the path to the compressed tar archive.
// This file should exist in the 'temp' directory.
// The archive is expected to be a gzip-compressed tar file.
let path = "temp/archive.tar.gz";
let tar_gz = File::open(path)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
// The archive will be unpacked into the 'temp' directory.
archive.unpack("temp")?;
println!("archive file unpacked!");
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;
use std::fs::File;
use flate2::Compression;
use flate2::write::GzEncoder;
/// This function creates a compressed tar archive (tar.gz) of the 'tests'
/// directory.
pub fn main() -> Result<(), std::io::Error> {
// Create a temporary folder
if !fs::exists("temp")? {
fs::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 e.g. the `tests` directory and all of its contents
// (recursively), renaming it in the process
tar.append_dir_all("backup", "./tests")?;
println!("`archive.tar.gz` file created!");
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;
/// This example demonstrates how to extract a tar archive while stripping a
/// common prefix from the paths of the extracted files.
///
/// It opens a gzipped tar archive, iterates over its entries, strips the
/// "bundle/logs" prefix, and unpacks the files to the new paths.
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(())
}