首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Okio正确读取块文件?

如何使用Okio正确读取块文件?
EN

Stack Overflow用户
提问于 2020-12-20 18:37:19
回答 1查看 844关注 0票数 0

我正在尝试使用一个文件上传API,该API要求文件以大小为单位的块上载,该块大小为它从以前的API调用中指定的字节。所以..。例如,如果文件很小,它将以1MB的块(以字节为单位)进行上传,但它很大,它可以说是以10 me块的形式上载它,如果它非常小,它可能只是返回文件大小,表明我应该一次性上传它。关键是我不能提前知道。它还需要我指定块的顺序作为查询参数,因此我需要在遍历文件块时跟踪我试图上传的块号。

无论如何,我在我的项目中使用Retrofit / OkHttp,并且认为这应该是Okio的一个很好的用法。这是我目前所拥有的,而且似乎奏效了。但是我是Okio的新手,我不知道我是不是遗漏了一些显而易见的东西,或者这是否可以用一种更好的方式完成。

代码语言:javascript
复制
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),然后使用更新的offsetblockNumber再次调用chunkedUpload方法。就像我说的,它有效,但我对Okio并不熟悉,我想知道我是否错过了一些显而易见的东西?

我之所以要使用Okio,很大程度上是因为我将上传文件,通常在30 GB到1GB之间,所以不要想一次将所有这些都加载到内存中:)。

EN

回答 1

Stack Overflow用户

发布于 2021-02-14 18:22:01

这是我的代码,使用Okio和OkHttp从资产文件夹读取图像文件,并将其作为多部分/表单数据发送到请求体中。

你对的基本需求

创建一个OkHttpClient

  • Create a RequestBody对象

  • ,将您的RequestBody添加为一个multipart/form-data

  • Create,一个请求对象来添加您的RequestBody和Header,

  • 使用OkHttpClient来调用Request

  • ,向您的enqueue添加一个回调,这样您就可以得到响应bject

G 215

代码语言:javascript
复制
    // 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();

        }
    });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65383439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档