如何使用流解压缩 Reqwest/Hyper 响应?

bri*_*lov 4 rust reqwest

我需要下载一个 60MB 的 ZIP 文件并提取其中的唯一文件。我想下载它并使用流提取它。如何使用 Rust 实现这一点?

fn main () {
    let mut res = reqwest::get("myfile.zip").unwrap();
    // extract the response body to myfile.txt
}
Run Code Online (Sandbox Code Playgroud)

在 Node.js 中,我会做这样的事情:

http.get('myfile.zip', response => {
  response.pipe(unzip.Parse())
  .on('entry', entry => {
    if (entry.path.endsWith('.txt')) {
      entry.pipe(fs.createWriteStream('myfile.txt'))
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

Tim*_*ann 5

有了reqwest你可以得到的.zip文件:

reqwest::get("myfile.zip")
Run Code Online (Sandbox Code Playgroud)

由于reqwest只能用于检索文件,因此ZipArchivezipcrate 中可用于解包。不可能将.zip文件流式传输到 中ZipArchive,因为ZipArchive::new(reader: R)需要R实现Read(由Responseof 实现reqwest)和Seek,而Response.

作为解决方法,您可以使用临时文件:

copy_to(&mut tmpfile)
Run Code Online (Sandbox Code Playgroud)

作为File实现SeekReadzip可以在这里使用:

zip::ZipArchive::new(tmpfile)
Run Code Online (Sandbox Code Playgroud)

这是所描述方法的一个工作示例:

extern crate reqwest;
extern crate tempfile;
extern crate zip;

use std::io::Read;

fn main() {
    let mut tmpfile = tempfile::tempfile().unwrap();
    reqwest::get("myfile.zip").unwrap().copy_to(&mut tmpfile);
    let mut zip = zip::ZipArchive::new(tmpfile).unwrap();
    println!("{:#?}", zip);
}
Run Code Online (Sandbox Code Playgroud)

tempfile 是一个方便的 crate,它可以让你创建一个临时文件,所以你不必想一个名字。


mgu*_*gul 3

这就是我读取文件hello.txt 的方式,其中包含本地服务器上hello world存档hello.zip的内容:

extern crate reqwest;
extern crate zip;

use std::io::Read;

fn main() {
    let mut res = reqwest::get("http://localhost:8000/hello.zip").unwrap();

    let mut buf: Vec<u8> = Vec::new();
    let _ = res.read_to_end(&mut buf);

    let reader = std::io::Cursor::new(buf);
    let mut zip = zip::ZipArchive::new(reader).unwrap();

    let mut file_zip = zip.by_name("hello.txt").unwrap();
    let mut file_buf: Vec<u8> = Vec::new();
    let _ = file_zip.read_to_end(&mut file_buf);

    let content = String::from_utf8(file_buf).unwrap();

    println!("{}", content);
}
Run Code Online (Sandbox Code Playgroud)

这将输出hello world