5

I need to download a 60MB ZIP file and extract the only file that comes within it. I want to download it and extract it using streams. How can I achieve this using Rust?

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

In Node.js I would do something like this:

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

2 回答 2

5

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

reqwest::get("myfile.zip")

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

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

copy_to(&mut tmpfile)

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

zip::ZipArchive::new(tmpfile)

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

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);
}

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

于 2018-05-22T15:57:20.663 回答
1

这就是我从位于本地服务器上的存档hello.zip中读取文件hello.txt的方式:hello world

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);
}

这将输出hello world

于 2018-05-22T15:57:03.347 回答