使用tar包
解压 tar 包
以下代码将解压缩( GzDecoder )当前目录中的 archive.tar.gz
,并将所有文件抽取出( 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 包
以下代码将 /var/log
目录压缩成 archive.tar.gz
:
- 创建一个 File 文件,并使用 GzEncoder 和 tar::Builder 对其进行包裹
- 通过 Builder::append_dir_all 将
/var/log
目录下的所有内容添加到压缩文件中,该文件在backup/logs
目录下。 - GzEncoder 负责在写入压缩文件
archive.tar.gz
之前对数据进行压缩。
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(()) }
解压的同时删除指定的文件前缀
遍历目录中的文件 Archive::entries,若解压前的文件名包含 bundle/logs
前缀,需要将前缀从文件名移除( Path::strip_prefix )后,再解压。
use std::fs::File; use std::path::PathBuf; use flate2::read::GzDecoder; use tar::Archive; 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 处理 .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(()) }