Работа с tar-архивами

Распаковка tar-архива

flate2-badge tar-badge cat-compression-badge

Пример разжимает с помощью (GzDecoder) и распаковывает с помощью (Archive::unpack) все файлы из сжатого tar-архива archive.tar.gz в текущем рабочем каталоге. Распаковка осуществляется в том же самом каталоге.

extern crate flate2;
extern crate tar;

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

fn main() -> Result<(), std::io::Error> {
    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(())
}

Запаковка каталога в tar-архив

flate2-badge tar-badge cat-compression-badge

Сжатие каталога /var/log directory в archive.tar.gz.

Этот пример создаёт File, обёрнутый в GzEncoder и tar::Builder. Рекурсивно добавляет содержимое каталога /var/log в архив по пути backup/logs с помощью Builder::append_dir_all. GzEncoder ответственен за прозрачный интерфейс для сжатия данных до записи их в файл archive.tar.gz.

extern crate tar;
extern crate flate2;

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

fn main() -> Result<(), std::io::Error> {
    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(())
}

Распаковка tar-архива с удалением префиксов путей

flate2-badge tar-badge cat-compression-badge

Код в примере итерируется с помощью Archive::entries. Мы используем Path::strip_prefix, чтобы удалить заданный префикс (bundle/logs). Наконец, распаковываем каждый tar::Entry с помощью Entry::unpack.

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

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

error_chain! {
  foreign_links {
    Io(std::io::Error);
    StripPrefixError(::std::path::StripPrefixError);
  }
}

fn main() -> 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(())
}