我正在尝试使用一个文件上传API,该API要求文件以大小为单位的块上载,该块大小为它从以前的API调用中指定的字节。所以..。例如,如果文件很小,它将以1MB的块(以字节为单位)进行上传,但它很大,它可以说是以10 me块的形式上载它,如果它非常小,它可能只是返回文件大小,表明我应该一次性上传它。关键是我不能提前知道。它还需要我指定块的顺序作为查询参数,因此我需要在遍历文件块时跟踪我试图上传的块号。
无论如何,我在我的项目中使用Retrofit / OkHttp,并且认为这应该是Okio的一个很好的用法。这是我目前所拥有的,而且似乎奏效了。但是我是Okio的新手,我不知道我是不是遗漏了一些显而易见的东西,或者这是否可以用一种更好的方式完成。
private void chunkedUpload(int offset, int chunkSize, int blockNumber, @Nonnull CompletableFuture<Foo> future) {
File file = ...
String url = ...
try (final BufferedSource bufferedSource = Okio.buffer(Okio.source(file))) {
bufferedSource.skip(offset);
final Buffer buffer = new Buffer();
final boolean isFinal = !bufferedSource.request(chunkSize);
bufferedSource.read(buffer, chunkSize);
final RequestBody requestFile = RequestBody.create(buffer.readByteArray(), null);
upload(offset, chunkSize, url, requestFile, blockNumber, future, isFinal);
} catch (IOException e) {
future.completeExceptionally(e);
}
}
private void upload(int offset, int chunkSize, @Nonnull String url, @Nonnull RequestBody requestFile, int blockNumber, @Nonnull CompletableFuture<Foo> future, boolean isFinal) {
fileUloadService.uploadApp(url + "&block_number=" + blockNumber, requestFile)
.whenComplete((responseBody, throwable) -> {
if (throwable != null) {
future.completeExceptionally(throwable);
} else {
if (isFinal) {
future.complete();
return;
}
chunkedUpload(offset + chunkSize, chunkSize, blockNumber + 1, future);
}
});
}您可以看到,我正在绑定上载块,等待成功响应(来自Java8 CompletableFuture),然后使用更新的offset和blockNumber再次调用chunkedUpload方法。就像我说的,它有效,但我对Okio并不熟悉,我想知道我是否错过了一些显而易见的东西?
我之所以要使用Okio,很大程度上是因为我将上传文件,通常在30 GB到1GB之间,所以不要想一次将所有这些都加载到内存中:)。
发布于 2021-02-14 18:22:01
这是我的代码,使用Okio和OkHttp从资产文件夹读取图像文件,并将其作为多部分/表单数据发送到请求体中。
你对的基本需求
创建一个OkHttpClient
G 215
// Read image file from the assets folder
BufferedSource img = Okio.buffer(Okio.source(getAssets().open("image.jpg")));
byte[] image = img.readByteArray();
// Create the OkHttpClient
OkHttpClient client = new OkHttpClient().newBuilder().build();
// Create the request body
RequestBody rq = RequestBody.create(MediaType.parse("image/jpeg"),image);
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("image", "image.jpg", rq)
.build();
// Create the request and add the RequestBody to it
Request request = new Request.Builder()
.url(YOUR_URL)
.method("POST", body)
.addHeader("Authorization", "Bearer " + BEARER_TOKEN)
.build();
// Use OkHttpClient to call the request
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Snackbar.make(upload, "Error", Snackbar.LENGTH_SHORT).show();
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
Snackbar.make(upload, "Success", Snackbar.LENGTH_SHORT).show();
}
});https://stackoverflow.com/questions/65383439
复制相似问题