question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ktor Client - Downloading large files with ByteReadChannel

See original GitHub issue

Hello guys,

I’m developing a Kotlin Multiplatform app for Android and iOS. The app should be able to download large files via HTTP by writing the data directly into a local file. The following code works perfectly for small files (I tried it with files smaller than 1 MB).

fileWriter.initialize()

val httpRequest = HttpRequestBuilder().apply {
    url("…")
    header("Authorization", "Bearer …")
}

httpClient.get(httpRequest).execute { response: HttpResponse ->
    val bytes = response.receive<ByteReadChannel>()

    val byteBufferSize = 1024 * 100
    val byteBuffer = ByteArray(byteBufferSize)

    do {
        val currentRead = bytes.readAvailable(byteBuffer, 0, byteBufferSize)

        if (currentRead > 0) {
            println("Write ${currentRead} bytes...")

            // write the data into the file
            fileWriter.writeToFile(if (currentRead < byteBufferSize) {
                byteBuffer.slice(0 until currentRead)
            } else {
                byteBuffer
            })
        }
    } while (currentRead >= 0)

    fileWriter.finish()
}

I tried to download a 2 GB file, but the app is stuck inhttpClient.get(httpRequest) until the RAM usage is too high and the OS decides to kill my app. I would expect that response.receive<ByteReadChannel>() streams the content of the request and I can read it step by step with bytes.readAvailable(…), but the code actually never reaches bytes.readAvailable(…).

Why is httpClient.get(httpRequest) downloading the 2 GB intead of streaming the data? How would you approach this and how can you download a large file without filling the RAM with the Ktor client?

Thank you! 😃

Edit: I tested the described scenario only on iOS so far. Ktor version: 1.3.1 Kotlin version: 1.3.61

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
e5lcommented, Feb 29, 2020

Streaming support and download is fixed in master. The fix will be available with the next minor release.

0reactions
dmitrievanthonycommented, Feb 19, 2020

As far as I remember, native clients don’t implement streaming so far, they download the whole response at first and only after that return it to you. As a result, if your response is big it will be fully loaded into the memory and may cause OOM.

Hi @cy6erGn0m, @e5l, please correct me if I’m wrong.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How can I download a large file with Ktor and Kotlin with a ...
1 Answer 1 ; 0 val byteBufferSize = 1024 ; 100 val channel = it.receive<ByteReadChannel>() val ; 0 val data ...
Read more >
ByteReadChannel - ktor
Channel for asynchronous reading of sequences of bytes. This is a single-reader channel. Operations on this channel cannot be invoked concurrently.
Read more >
Ktor HttpClient unable to download files larger than 4096 bytes
Ktor Client 1.3.1 in Kotlin MPP context. Engines OkHTTP and iOS Native, but not explicitly set (resolved by gradle dependency). Describe the bug....
Read more >
Download files with Ktor client, Koin and Coroutines
A simple guide to download files in a RecyclerView with Ktor and Koin ... So Ktor-client and Kotlin coroutines provide together awesome facilities...
Read more >
样例 Reverse Proxy - Ktor
Reverse Proxy and Asynchronous Streaming using Ktor Client and Server ... In the case of other files, the file is streamed from the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found