Работа с 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(()) }