Есть ли способ, с помощью которого можно запускать некоторую функцию для каждого блока данных?
Hyper's Response
осуществляет Read
. Это означает, что Response
является потоком, и вы можете читать произвольные фрагменты данных, как обычно, с потоком.
Для чего это стоит, вот фрагмент кода, который я использую для загрузки больших файлов из ICECat. Я использую интерфейс Read
, чтобы отобразить процесс загрузки в терминале.
Переменная response
здесь является примером Hyper's 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();
Я хочу, чтобы загрузить большие файлы (500MB) с гипер, и быть в состоянии возобновить, если загрузка не выполняется.
Обычно это осуществляется с заголовком HTTP «Range» (см. RFC 7233).
Не каждый сервер поддерживает заголовок «Range». Я видел много серверов с настраиваемым стеке HTTP и без надлежащей поддержки «Range», или с отключенным заголовком «Range» по какой-то причине. Таким образом, пропуск Hyper's Response
может быть необходимым резервом.
Но если вы хотите сэкономить время и трафик, то основным средством возобновления остановки загрузки должно быть использование заголовка «Range».
'read' сам по себе, не так ли? Вы можете читать N байтов за раз. Я не уверен, что это соотносится с точно загруженными N байтами или если это просто буферизованное чтение. Но это не имеет большого значения, если вы правильно сохраните данные. – Kroltan