Работа с tar-архивами
Распаковка tar-архива
Пример разжимает с помощью (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-архив
Сжатие каталога /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-архива с удалением префиксов путей
Код в примере итерируется с помощью 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(()) }