使用文件流上传文件 #190
liangjingkanji
started this conversation in
Ideas
使用文件流上传文件
#190
Replies: 2 comments
/**
* 创建输入流的ResponseBody
*
* @param contentLength 如果不指定长度默认将使用[InputStream.available]作为长度
*
* https://github.com/square/okhttp/issues/3585
* 1. 在需要重复读取输入流时会导致错误
* 2. 零次读取请求体导致输入流内存泄露
*
* 建议使用以下方法替代
* @see File.toRequestBody
* @see Uri.toRequestBody
*
* 如果重复读取抛出[IllegalStateException]
*/
@Throws(IllegalStateException::class)
fun InputStream.toRequestBody(
contentType: MediaType? = MediaConst.OCTET_STREAM,
contentLength: Long? = null
): RequestBody {
return object : RequestBody() {
override fun contentType() = contentType
val availableLength: Long by lazy {
if (contentLength != null) return@lazy contentLength
// 如果输入流字节过长超过Int.MAX_VALUE会无法获取到正确内容长度
val availableLength = available()
if (availableLength == 0) -1L else availableLength.toLong()
}
override fun contentLength(): Long {
return availableLength
}
override fun writeTo(sink: BufferedSink) {
source().use { source ->
sink.writeAll(source)
}
}
override fun isOneShot(): Boolean {
// 由于输入流只允许读取一次, 所以禁止请求重试
return true
}
}
} |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
关于此问题, 我修改了很多次, 但这由框架来实现可能会引发超出预期的问题发生
官方对此也有讨论 lysine-dev/okhttp#3585
建议是将
InputStream先写入到File中, 或者使用Uri.toRequestBody替代All reactions