使用文件流上传文件 #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
}
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
-
Duplicate #189 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
关于此问题, 我修改了很多次, 但这由框架来实现可能会引发超出预期的问题发生
官方对此也有讨论 square/okhttp#3585
建议是将
InputStream
先写入到File中, 或者使用Uri.toRequestBody
替代Beta Was this translation helpful? Give feedback.
All reactions