受信したデータの各チャンクに対していくつかの機能を実行する方法はありますか。
ハイパーのResponse
は、Read
を実装しています。これは、Response
がストリームであることを意味し、通常はストリームと同様に、任意のチャンクを読み込むことができます。
ここでは、ICECatから大きなファイルをダウンロードするためのコードを紹介します。私はRead
インターフェイスを使用して、端末のダウンロードの進行状況を表示しています。
ここで変数response
はHyperのResponse
のインスタンスです。
{
let mut file = try_s!(fs::File::create(&tmp_path));
let mut deflate = try_s!(GzDecoder::new(response));
let mut buf = [0; 128 * 1024];
let mut written = 0;
loop {
status_line! ("icecat_fetch] " (url) ": " (written/1024/1024) " MiB.");
let len = match deflate.read(&mut buf) {
Ok(0) => break, // EOF.
Ok(len) => len,
Err(ref err) if err.kind() == io::ErrorKind::Interrupted => continue,
Err(err) => return ERR!("{}: Download failed: {}", url, err),
};
try_s!(file.write_all(&buf[..len]));
written += len;
}
}
try_s!(fs::rename(tmp_path, target_path));
status_line_clear();
私はハイパーで大きなファイル(500メガバイト)をダウンロードし、ダウンロードが失敗した場合に再開できるようにしたいです。
これは、通常、HTTP "Range"ヘッダー(RFC 7233参照)で実装されます。
「範囲」ヘッダーがサポートされているサーバーはありません。私はカスタムHTTPスタックを備え、適切な "Range"サポートがない、または何らかの理由で "Range"ヘッダーが無効になっているサーバーをたくさん見てきました。したがって、HyperのResponse
チャンクをスキップすることは必要な代替手段かもしれません。
しかし、時間とトラフィックを節約したい場合は、停止したダウンロードを再開するための主な手段は、「範囲」ヘッダーを使用することです。
'read'自体がチャンクされていますか?一度にNバイトを読み取ることができます。私はそれがダウンロードされたNバイトに正確に相関するかどうか、またはちょうどバッファされた読み取りであるかどうかはわかりません。しかし、データを適切に保存する限り、それは重要ではありません。 – Kroltan