Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Streaming Downloads

aioduct supports streaming response bodies chunk-by-chunk, avoiding the need to buffer the entire response in memory. This is essential for downloading large files.

BodyStream

Convert a response into a BodyStream that yields Bytes chunks:

use aioduct::TokioClient;

#[tokio::main]
async fn main() -> Result<(), aioduct::Error> {
    let client = TokioClient::new();

    let resp = client
        .get("http://example.com/large-file.bin")?
        .send()
        .await?;

    let mut stream = resp.into_bytes_stream();
    let mut total = 0usize;
    while let Some(chunk) = stream.next().await {
        let chunk = chunk?;
        total += chunk.len();
        // process chunk...
    }

    println!("downloaded {total} bytes");
    Ok(())
}

Streaming to a File

Combine BodyStream with tokio::fs::File to download directly to disk:

use aioduct::TokioClient;
use tokio::io::AsyncWriteExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = TokioClient::new();

    let resp = client
        .get("http://example.com/large-file.bin")?
        .send()
        .await?;

    let mut file = tokio::fs::File::create("output.bin").await?;
    let mut stream = resp.into_bytes_stream();

    while let Some(chunk) = stream.next().await {
        file.write_all(&chunk?).await?;
    }
    file.flush().await?;

    Ok(())
}

Choosing Between Methods

MethodUse CaseMemory
resp.bytes()Small responses, read all at onceEntire body in memory
resp.text()Small text responsesEntire body in memory
resp.into_bytes_stream()Large downloads, progress trackingOne chunk at a time
resp.into_sse_stream()Server-Sent EventsOne event at a time