2016-10-27 43 views
2

Hyper具有功能fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>可將HTTP響應的內容讀取到提供的&mut [u8]中。使用Hyper和Flate2讀取gzip響應

Flate2可以用gunzip:

let mut d = GzDecoder::new("...".as_bytes()).unwrap(); 
let mut s = String::new(); 
d.read_to_string(&mut s).unwrap(); 
println!("{}", s); 

我嘗試了兩件事情放在一起:

fn gunzip(r: &Response) -> String { 
    let mut zs: &mut [u8] = &mut[]; 
    r.read(zs); 
    let mut d = GzDecoder::new(zs).unwrap(); 
    let mut s = String::new(); 
    d.read_to_string(&mut s).unwrap(); 
    s 
} 

而我得到的錯誤:

error[E0277]: the trait bound `[u8]: std::io::Read` is not satisfied 
    --> tests/integration.rs:232:21 
    | 
232 |   let mut d = GzDecoder::new(zs).unwrap(); 
    |      ^^^^^^^^^^^^^^ trait `[u8]: std::io::Read` not satisfied 
    | 
    = help: the following implementations were found: 
    = help: <&'a [u8] as std::io::Read> 
    = note: required because of the requirements on the impl of `std::io::Read` for `&mut [u8]` 
    = note: required by `<flate2::read::DecoderReader<R>>::new` 

我要去哪裏錯了?


編輯:最後的工作液:

fn gunzip(r: &mut Response) -> String { 
    let mut buffer = Vec::new(); 
    let _ = r.read_to_end(&mut buffer).unwrap(); 
    let mut d = GzDecoder::new(buffer.as_slice()).unwrap(); 
    let mut s = String::new(); 
    d.read_to_string(&mut s).unwrap(); 
    s 
} 
+0

(迴應刪除的評論...)是的,我做了[嘗試&zs']。結果'trait'&& mut [u8]:std :: io :: Read'not satisfied'。 – Synesso

+0

你可以嘗試添加第二個&它嗎? (這聽起來很愚蠢,但它適用於[playground](https://play.rust-lang.org/?code=use%20std%3A%3Aio%3A%3ARead%3B%0A%0Afn%20foo(r %3A%20%26Read)%20%7B%0A%20%20%20%20%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20let%20mut% 20A%20%3D%20%5B8u8%2C%206%2C%207%5D%3B%0A%20%20%20%20let%20mut%20bind%20%3D%20%26A%3B%0A%20% 20%20%20%0%20%20%20%20foo(%26%26bind%5B ..%5D)%3B%0A%7D&version = stable&backtrace = 0)) – Neikos

+0

'GzDecoder :: new(&& zs).unwrap ()'=>'trait'&&& mut [u8]:std :: io :: Read'not satisfied'。 – Synesso

回答

1

GzDecoder::new的參數與泛型類型定義的,所以鏽病不會執行一些轉換,將如果固定式,預計發生。

您可以通過解引用可變片,然後對結果進行引用,將可變片轉換爲不可變片。

let mut d = GzDecoder::new(&*zs).unwrap(); 
+0

W!!但它的工作。 – Synesso

1

這裏是另一種方式,你可以做到這一點,而不使用另一個緩衝區:

extern crate hyper; 
extern crate flate2; 

use std::io::Read; 

use hyper::client::Client; 
use hyper::header::{Headers, AcceptEncoding, Encoding, qitem}; 

use flate2::read::GzDecoder; 

fn main() { 
    let c = Client::new(); 

    let mut req = c.get("http://httpbin.org/gzip"); 
    let mut headers = Headers::new(); 
    headers.set(
     AcceptEncoding(vec![qitem(Encoding::Gzip)]) 
    ); 
    req = req.headers(headers); 

    let res = req.send().unwrap(); 
    let mut decoder = GzDecoder::new(res).unwrap(); 
    let mut buf = String::new(); 

    let _ = decoder.read_to_string(&mut buf); 
    println!("{}", buf); 
} 

此示例使用從HTTPBIN的gzip端點檢測,該Response可以在GzDecoder使用。

[dependencies] 
hyper = "0.9" 
flate2 = "0.2" 

附註:

在我的貨運文件中使用

依賴unwrap()電話是爲了簡潔起見:)