【发布时间】:2022-01-23 16:43:30
【问题描述】:
我正在尝试将文件上传到 s3 存储桶,但收到 400 错误请求或找不到文件。
我尝试了各种解决方案,但仍然没有运气。
解决方案 1:
class InputStreamRequestBody(
private val contentResolver: ContentResolver,
private val uri: Uri
): RequestBody() {
override fun contentType(): MediaType? =
contentResolver.getType(uri)?.toMediaTypeOrNull()
override fun writeTo(sink: BufferedSink) {
contentResolver.openInputStream(uri)?.source()?.use(sink::writeAll)
}
override fun contentLength(): Long =
contentResolver.query(uri, null, null, null, null)?.use { cursor ->
val sizeColumnIndex: Int = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
cursor.getLong(sizeColumnIndex)
} ?: super.contentLength()
}
像这样使用它
@Multipart
@PUT
fun uploadFile(@Url url: String, @Part file: MultipartBody.Part): Single<Response<Any>>
val file = File(uri.path)
val requestBody = InputStreamRequestBody(contentResolver!!, uri)
val filePart = MultipartBody.Part.createFormData("file", file.name, requestBody)
packageApi.uploadFile(url, filePart)
这会导致错误请求
解决方案 2:
和之前一样,但这次没有 Multipart
@PUT
fun uploadFile(@Url url: String, @Body file: RequestBody): Single<Response<Any>>
val requestBody = InputStreamRequestBody(contentResolver!!, uri)
packageApi.uploadFile(url, requestBody)
这也会导致错误请求
解决方案 3:
现在我放弃了InputStreamRequestBody类,使用here提到的传统方式
@Multipart
@PUT
fun uploadFile(@Url url: String, @Part file: MultipartBody.Part): Single<Response<Any>>
val file = File(uri.path)
val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
packageApi.uploadFile(url, body)
这会导致 java.io.FileNotFoundException: /document/image:95: open failed: ENOENT (No such file or directory)
感谢任何建议/解决方案!
【问题讨论】:
标签: android amazon-s3 retrofit okhttp