【问题标题】:How to read specific file from zip file如何从 zip 文件中读取特定文件
【发布时间】:2021-09-20 19:35:25
【问题描述】:

我完全无法从 zip 文件的可变路径结构中读取文件而不解压缩它。

我的文件位于此处:

/info/[random-string]/info.json

其中 [random-string] 是 info 文件夹中的唯一文件。 所以它就像读取'info'文件夹读取第一个文件夹读取'info.json'。

任何想法如何使用这些库之一(ziprc_zip)来做到这一点?

let file_path = file.to_str().unwrap();
let file = File::open(file_path).unwrap();
let reader = BufReader::new(file);

let mut archive = zip::ZipArchive::new(reader).unwrap();
let info_folder = archive.by_name("info").unwrap();
// how to list files of info_folder

【问题讨论】:

  • 你知道如何列出目录中的所有条目吗?
  • 我可以想象您的想法,但不幸的是,这两个库的文档都不完整。所以我希望这里有人很了解他们中的一个。
  • 文档齐全;有用于从档案中读取并专门用于列出条目的 API。你看过那些并尝试过使用它们吗?
  • 从您的第一个链接read,然后ZipArchive 将您带到file_names
  • 第一层的标识很清楚。从这一点深入到下一个层次是问题所在。我已经更新了我的问题。

标签: rust zip


【解决方案1】:

你在这里:

use std::error::Error;
use std::ffi::OsStr;
use std::fs::File;
use std::path::Path;
use zip::ZipArchive; // zip 0.5.13

fn main() -> Result<(), Box<dyn Error>> {
    let archive = File::open("./info.zip")?;
    let mut archive = ZipArchive::new(archive)?;

    // iterate over all files, because you don't know the exact name
    for idx in 0..archive.len() {
        let entry = archive.by_index(idx)?;
        let name = entry.enclosed_name();
        
        if let Some(name) = name {
            // process only entries which are named  info.json
            if name.file_name() == Some(OsStr::new("info.json")) {
                // the ancestors() iterator lets you walk up the path segments
                let mut ancestors = name.ancestors();
               
                // skip self - the first entry is always the full path
                ancestors.next(); 

                // skip the random string
                ancestors.next(); 

                let expect_info = ancestors.next(); 

                // the reminder must be only 'info/' otherwise this is the wrong entry
                if expect_info == Some(Path::new("info/")) {
                    // do something with the file
                    println!("Found!!!");
                    break;
                }
            }
        }
    }

    Ok(())
}

【讨论】: