我正在尝试使用一个文件上传api,该api要求将文件以字节大小的块上传,这是它从以前的api调用中指定的。所以。。。。例如,如果文件很小,它会说上传它在1mb的块(字节),但它是大的,它可能会说上传它在10mb的块,如果它真的很小,它可能只是返回我的文件大小,表明我应该上传它一次。关键是我不能提前知道。它还需要我指定块的顺序作为一个查询参数,这样我就需要在循环遍历文件的块时跟踪我试图上载的块编号。
不管怎样,我在我的项目中使用了reformation/okhttp,并且认为这应该是一个很好的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
)然后打电话给 chunkedUpload
方法再次更新 offset
以及 blockNumber
. 就像我说的,这很管用,但我对okio还很陌生,不知道我是否错过了一些明显的东西?
我之所以要使用okio,很大程度上是因为我要上传的文件通常在30mb到1GB之间,所以不要想一次将所有这些文件加载到内存中:)。
暂无答案!
目前还没有任何答案,快来回答吧!