使用 tar 包

解压 tar 包

flate2-badge tar-badge cat-compression-badge

从当前工作目录中的压缩包 archive.tar.gz,解压(GzDecoder)和提取(Archive::unpack)所有文件,并放在同一位置。

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 目录内的内容到 archive.tar.gz 压缩包中。

创建一个用 GzEncodertar::Builder 包裹的 File

使用 Builder::append_dir_all,将 /var/log 目录内的内容递归添加到 backup/logs 路径下的归档文件中。在将数据写入压缩包 archive.tar.gz 之前,GzEncoder 负责清晰地将数据压缩。

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)。最终,通过 Entry::unpack 提取 tar::Entry(tar 包中的内容)。

use error_chain::error_chain; 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(()) }