【问题标题】:does okhttp check for whether the response is complete or not for chunked responsesokhttp 检查分块响应的响应是否完整
【发布时间】:2021-05-16 09:36:25
【问题描述】:

我从服务器接收到一个无法保存在内存中的大文件,因此以分块编码响应的形式接收它,并通过 okhttp Response.body().source() 将其读取到缓冲区中并将其写入如下文件。


val downloadFileBuffer = ByteArray(1024)

client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.d("DOCUMENT_CONVERSION", "FAILED", e)
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val source = response.body()?.source()
                    while (!source?.exhausted()!!) {
                        source?.read(downloadFileBuffer)
                        downloadFileStream.write(downloadFileBuffer) // downloadFileStream being a FileOutputStream
                    }
                    response.close()

                } else {
                    // error handling
                    response.close()
                }
            }
        })

分块响应将以接收到的空零字节块结束。为了将整个文件写入磁盘,我需要检查是否收到了直到结束零字节块的整个响应。

我想知道 okhttp 是否有内部机制通过onFailure 或任何其他方式检查分块响应是否完整,或者它应该由我在应用程序级别处理?如果在传输过程中出现网络故障并且无法接收最后几个字节导致文件损坏怎么办?

【问题讨论】:

    标签: android kotlin okhttp


    【解决方案1】:

    如果您收到分块响应,则不会调用 onFailure,然后在响应传输过程中失败。

    如果传输未完成,您将在调用 source.read 时收到 IOException。

    这个循环的一个更简洁的例子在这里https://github.com/square/okhttp/blob/c194980c7f0feee59c978766c1acf5c66167994c/okcurl/src/main/kotlin/okhttp3/curl/Main.kt#L139-L143

          val source = response.body!!.source()
          while (!source.exhausted()) {
            out.write(source.buffer, source.buffer.size)
            out.flush()
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-02
      • 2011-03-21
      • 1970-01-01
      相关资源
      最近更新 更多