https://kotlinlang.org logo
#ktor
Title
# ktor
s

spierce7

01/25/2021, 3:21 AM
I’m trying to download a file directly to disk with ktor. I’m using the ktor streaming api, but I’m still seeing my memory on device go from 64MB to 200+MB (about the size of the file) while the large file is downloading. What am I doing wrong? Code in thread.
Copy code
suspend fun downloadVideo(
    httpClient: HttpClient,
    url: String,
    to: File,
): Flow<Float> = flow {
    emit(0f)
    val response = httpClient.get<HttpStatement>(url).execute()

    val fileWriter = to.outputStream()
    val bytes = response.receive<ByteReadChannel>()

    try {
        val byteBufferSize = 1024 * 100
        val byteBuffer = ByteArray(byteBufferSize)
        val contentLength = response.contentLength()
        var totalRead = 0

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

            if (currentRead > 0) {
                totalRead += currentRead

                if (contentLength != null) {
                    val progressPercent = totalRead / contentLength.toFloat()
                    val floorProgressPercent = (progressPercent * 100).toInt() / 100f
                    emit(floorProgressPercent)
                }

                fileWriter.write(byteBuffer, 0, currentRead)
            }
        } while (currentRead >= 0)

    } finally {
        fileWriter.flush()
        fileWriter.close()
    }

    emit(100f)
}.flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
c

cy

01/25/2021, 8:01 AM
You should use execute with block inatead otherwise it reads thre whole content
s

spierce7

01/25/2021, 3:14 PM
Really? Why? That’s extremely non-obvious
6 Views