Search code examples
iokotlinokhttpandroid-file

Difficulty writing downloaded pdf file to android device


I am downloading a pdf file from a web server using okhttp. The file appears to download correctly, and the file "Test.pdf" is created. The file size is listed as 0 however in the Device File Explorer in Android Studio.

Here is my callback code:

client.newCall(request).enqueue(object : Callback {

    override fun onFailure(call: Call, e: IOException) {
                    println("Failed")
                }

    override fun onResponse(call: Call, response: Response) {

                    println("Success!")

                    val file = File(filesDir, "Test.pdf")
                    println(response.body()!!.bytes().size)

                    file.outputStream().write(response.body()!!.bytes())
                    file.outputStream().flush()
                    file.outputStream().close()
                }
            })

The println statement shows the correct file size of 6MB. I am really unsure why the file is not writing to the device.


Solution

  • You're opening a new OutputStream with every new call of the outputStream function. Instead, you can use just one:

    val os = file.outputStream()
    os.write(response.body()!!.bytes())
    os.flush()
    os.close()
    

    And you might wanna wrap it in a use block instead of closing it yourself (and flushing it isn't necessary):

    file.outputStream().use { os ->
        os.write(response.body()!!.bytes())
    }
    

    And if you only need to write a single ByteArray, the writeBytes method that was already suggested by @ice1000 does the above with even less code:

    file.writeBytes(response.body()!!.bytes())
    

    And while here, I'd perform a null check on the response body just to be safe:

    val responseBytes = response.body()?.bytes()
    if (responseBytes != null) {
        file.writeBytes(responseBytes)
    } else {
        // Handle error somehow
    }