You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级okhttp3后将PDF的ResponseBody写入外部存储报closed异常如何解决

问题修复方案

问题根因

  • 调用body.bytes()抛出closed异常:OkHttp的ResponseBody的bytes()方法读取完全部响应内容后会自动关闭底层流,后续再调用byteStream()读取时流已经被释放,因此抛出状态异常。
  • 使用body.contentLength()时写入失败的两个核心原因:
    1. 你配置的HttpLoggingInterceptor日志级别为BODY,高版本OkHttp中该级别会消费整个响应体内容用于打印,大文件场景下不仅会占用大量内存,还会导致后续你拿到的ResponseBody流已经为空,写入无内容。
    2. 原有代码逻辑存在疏漏:异常弹出的Toast未调用.show()方法,出现异常时你无法收到错误提示;流未做自动关闭处理,也没有校验写入结果,无法定位问题。

修复步骤

1. 调整OkHttp配置

下载文件专用的OkHttpClient实例建议关闭BODY级别的日志,避免流被提前消费:

// 调试阶段可以保留HEADERS级别日志,生产环境直接关闭日志即可
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(logging)
        .connectTimeout(2, TimeUnit.MINUTES)
        .writeTimeout(2, TimeUnit.MINUTES)
        .readTimeout(2, TimeUnit.MINUTES)
        .build();

2. 重写文件写入逻辑

不需要提前读取整个响应体获取长度,直接用缓冲区边读边写,避免大文件OOM的同时也不会触发流提前关闭的问题,同时用try-with-resources自动关闭流,补全异常提示:

private boolean writeResponseBodyToDisk(ResponseBody body) {
    File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    File targetFile = new File(downloadDir, "test.pdf");
    byte[] buffer = new byte[4096];
    int readLen;
    // try-with-resources会自动关闭输入输出流,不需要手动调用close
    try (InputStream inputStream = body.byteStream();
         OutputStream outputStream = new FileOutputStream(targetFile)) {
        while ((readLen = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, readLen);
        }
        outputStream.flush();
        Toast.makeText(MainActivity.this, "文件写入成功", Toast.LENGTH_SHORT).show();
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(MainActivity.this, "写入失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
        return false;
    }
}

3. 补充权限配置

如果你的应用targetSdkVersion >=23且运行在Android 9及以下系统,需要在代码中动态申请WRITE_EXTERNAL_STORAGE权限,Android 10及以上系统不需要申请该权限,可直接写入公共Download目录。

内容的提问来源于stack exchange,提问作者Niklaus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 11:24:01