Rust范例:使用 tar 压缩和解压缩

解压缩( GzDecoder )和 提取( Archive::unpack )一个压缩包 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(())
}

1. 将目录压缩为 tar 包

把 /var/log 目录压缩,为 archive.tar.gz 。

先创建一个 File ,传入压缩文件生成器 GzEncoder,最后使用 tar::Builder 构建 tar 包。

  • 用 Builder::append_dir_all 递归添加 /var/log 目录中的内容,归档到 backup/logs 路径下。
  • 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(())
}

2. 从路径中删除前缀,解压缩 tar 包

迭代 Archive::entries。使用 Path::strip_prefix 删除指定的路径前缀( bundle/logs )。最后,通过 Entry::unpack ,提取出 tar::Entry 压缩包中的项。

# #[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(())
}

下一章:Rust范例 哈希和签名

Rust范例:哈希摘要和数字签名:1. 计算文件的 SHA-256 码:将一些数据写入文件,然后获得文件的内容,再用使用 digest::Context,最后使用 digest::Digest 计算 SHA-256 码。2. 签署并验证消息:使用 ring::hmac 创建一个 hmac::Signature ,然后验证签名是否正确。