从 OKHTTP 下载二进制文件

2024-02-10

我在我的 Android 应用程序中使用 OKHTTP 客户端进行网络连接。

This https://stackoverflow.com/questions/25367888/upload-binary-file-with-okhttp-from-resources示例显示如何上传二进制文件。我想知道如何使用 OKHTTP 客户端获取二进制文件下载的输入流。

以下是示例的清单:

public class InputStreamRequestBody extends RequestBody {

    private InputStream inputStream;
    private MediaType mediaType;

    public static RequestBody create(final MediaType mediaType, 
            final InputStream inputStream) {
        return new InputStreamRequestBody(inputStream, mediaType);
    }

    private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
        this.inputStream = inputStream;
        this.mediaType = mediaType;
    }

    @Override
    public MediaType contentType() {
        return mediaType;
    }

    @Override
    public long contentLength() {
        try {
            return inputStream.available();
        } catch (IOException e) {
            return 0;
        }
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        Source source = null;
        try {
            source = Okio.source(inputStream);
            sink.writeAll(source);
        } finally {
            Util.closeQuietly(source);
        }
    }
}

简单获取请求的当前代码是:

OkHttpClient client = new OkHttpClient();
request = new Request.Builder().url("URL string here")
                    .addHeader("X-CSRFToken", csrftoken)
                    .addHeader("Content-Type", "application/json")
                    .build();
response = getClient().newCall(request).execute();

现在我如何将响应转换为InputStream。类似的回应Apache HTTP Client像这样OkHttp回复:

InputStream is = response.getEntity().getContent();

EDIT

接受下面的答案。 我修改后的代码:

request = new Request.Builder().url(urlString).build();
response = getClient().newCall(request).execute();

InputStream is = response.body().byteStream();

BufferedInputStream input = new BufferedInputStream(is);
OutputStream output = new FileOutputStream(file);

byte[] data = new byte[1024];

long total = 0;

while ((count = input.read(data)) != -1) {
    total += count;
    output.write(data, 0, count);
}

output.flush();
output.close();
input.close();

对于它的价值,我会推荐response.body().source() from okio https://github.com/square/okio#sources-and-sinks(因为 OkHttp 已经原生支持它)以便享受更简单的方式来操作下载文件时可能出现的大量数据。

@Override
public void onResponse(Call call, Response response) throws IOException {
    File downloadedFile = new File(context.getCacheDir(), filename);
    BufferedSink sink = Okio.buffer(Okio.sink(downloadedFile));
    sink.writeAll(response.body().source());
    sink.close();
}

与 InputStream 相比,从文档中可以看出一些优点:

该接口在功能上等同于InputStream。 当使用的数据是异构的时,InputStream 需要多个层:用于原始值的 DataInputStream、用于缓冲的 BufferedInputStream 以及用于字符串的 InputStreamReader。此类使用 BufferedSource 来实现上述所有功能。 Source 避免了不可能实现的 available() 方法。相反,调用者指定他们需要多少字节。

Source 忽略了由 InputStream 跟踪的不安全组合标记和重置状态;调用者只是缓冲他们需要的内容。

实现源时,您无需担心单字节读取方法,该方法难以高效实现并且返回 257 个可能值之一。

而source有一个更强的skip方法:BufferedSource.skip(long)不会过早返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 OKHTTP 下载二进制文件 的相关文章

  • Firebase 管理 SDK Android

    在 Android 中初始化 Firebase Admin SDK 的代码 Override protected void onCreate Bundle savedInstanceState super onCreate savedIns
  • 在应用程序简历中隐藏软键盘

    我有一个 Android 应用程序 使用 Xamarin 用 C 编写 我已将应用程序简化为包含 TextView 和用于横幅广告的 Google admod AdView 的 LinearLayout 我不希望软键盘出现在应用程序中 这不
  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • Android 应用程序在后台运行时保存数据

    目前我正在开发 xmmp 客户端 当应用程序位于前台时 该客户端工作得很好 但由于事实上 当应用程序处于后台时 我在 Application 类中保存了大量数据 复杂的 ArrayList 字符串和布尔值作为公共静态 每个字段都被垃圾收集
  • 导航组件重复 NavArgs 的问题

    我有一个片段 class SomeFragment private val args by navArgs
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • Android libgdx 首选项丢失

    我在 Libgdx 引擎中创建了 Android 游戏 一段时间后 我注意到在某些应用程序杀手中杀死该应用程序后 或者如果我在 Android 设置中执行 强制关闭 操作 我保存到首选项中的游戏选项就会丢失 有办法防止这种情况吗 我从来没有
  • RxJava、Proguard 和 sun.misc.Unsafe

    我有以下问题RxJava 1 1 0 使用时Proguard 我没有更改 RxJava 版本或其 pro文件 但更新后OkHttp我无法编译使用Proguard因为我有关于sun misc Unsafe不在场 rxJava pro keep
  • 如何在 sqlite 中将 2 列合并为新列

    我有一个包含 3 列的表 我必须将 2 列中的值按降序排列到一列中 A B C z 1 2 f 5 7 s 9 5 使用此示例 输出会将 B 列和 C 列中的值放入其中 如下所示 A B s 9 f 7 f 5 s 5 z 2 z 1 我当
  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • Android相机意图:如何获取全尺寸照片?

    我正在使用意图来启动相机 Intent cameraIntent new Intent android provider MediaStore ACTION IMAGE CAPTURE getParent startActivityForR
  • Android Studio:无法启动守护进程

    当我尝试在 Android Studio 中导入 gradle 项目时 遇到以下错误 Unable to start the daemon process This problem might be caused by incorrect
  • 材质设计图标颜色

    应该是哪种颜色 暗 材质图标 在官方文档上 https www google com design spec style icons html icons system icons https www google com design s
  • 通过 ADB 拔出设备:“找不到服务”

    我必须测试我的应用程序在打瞌睡模式下的行为 根据文档 https developer android com training monitoring device state doze standby html testing doze 我
  • 当手机旋转(方向改变)时如何最好地重新创建标记/折线

    背景 开发一个使用 Android Google Map v2 的本机 Android 应用程序 使用android support v4 app FragmentActivity 在 Android v2 2 上运行 客观的 在更改手机方
  • Android:有没有办法以毫安为单位获取设备的电池容量?

    我想获取设备的电池容量来进行一些电池消耗计算 是否可以以某种方式获取它 例如 三星 Galaxy Note 2 的电池容量为 3100mAh 谢谢你的帮助 知道了 在 SDK 中无法直接找到任何内容 但可以使用反射来完成 这是工作代码 pu
  • 用于推送通知的设备令牌

    我正在实施推送通知服务 我需要创建一个数据库来存储 4 个移动平台的所有设备令牌 我想根据他们的平台 iOS Android BlackBerry WP7 来组织它们 但是有什么方法可以区分平台 这样如果我只想向 Android 用户发送消
  • 为什么Android的ImageReader类这么慢?

    我尝试了适用于 Android 3 4 1 的全新 OpenCVJavaCamera2View但它太慢了 仅显示相机视图约 15 fps 当我尝试较旧的JavaCameraView相反 它给了我很好的结果 30fps 这是我相机的极限 我想
  • 在 Google 地图上绘制线条/路径

    我很长一段时间都在忙于寻找如何在 HelloMapView 中的地图上的两个 GPS 点之间画一条线 但没有运气 谁能告诉我该怎么做 假设我使用扩展 MapView 的 HelloMapView 我需要使用叠加层吗 如果是这样 我是否必须重

随机推荐

  • Mybatis Generator:如何生成指定模式的所有表

    Mysql数据库总共有4个模式 我只想生成一个名为 booking 的指定模式 但它总是为所有模式生成所有表 所以我需要你的帮助 下面是我的generatorConfig xml
  • CSSOM 和 DOM 创建是异步的吗?

    我读到 CSSOM 创建是网页性能的瓶颈 但似乎有一些方法可以解决这个问题 比如添加media样式表链接的属性 我试图了解如何优化我的网络应用程序 并发现了这个非常有趣的事情link https developers google com
  • 为什么使用 lme4 的线性混合模型的输出显示一个因子水平而不是另一个水平?

    我正在使用lme4打包并运行线性混合模型 但我很困惑 但输出并期望我遇到错误 即使我没有收到错误消息 基本问题是当我适合这样的模型时lmer Values stimuli timeperiod scale poly distance cod
  • Mongodb查询异常慢

    我的 mongodb 相当简单 一个数据集 条目在 3 层上有大约 30 个属性 此类条目最多可包含 5000 个字符左右 我有 500k 个 当我执行以下查询时 db images find featureData cedd exists
  • 如何在不使用文本字段的情况下在 MySQL 数据库中存储哈希值

    我正在存储独特的用户代理在 MySQL MyISAM 表中 因此当我必须查看它是否存在于表中时 我会检查md5 hash它存储在 TEXT 字段旁边 User Agents id INT user agent TEXT hash VARCH
  • 如何在 typescript / Angular 中设置子 html 元素的样式

    我正在使用 ionic 3 构建混合移动应用程序 要求之一是用户能够动态更改工具栏颜色 页面渲染后 html 如下所示 div this div i can control div but this one is generated by
  • Aurelia 有虚拟元素吗?

    Knockout JS有虚拟元素的概念 这些是 无头 元素 您可以将其绑定到没有 HTML 元素作为容器的元素 这允许您在不发出外部 HTML 的容器中绑定数组 例如 在 Knockout JS 中 您可以执行以下操作 li li 一系列l
  • 防止 WPF DataGrid 中的多行选择

    我在 WPF DataGrid 中有以下 XAML 标记
  • NLTK python 错误:“TypeError:‘dict_keys’对象不可下标”

    我正在按照课堂作业的说明进行操作 并且应该在文本文件中查找最常用的 200 个单词 这是代码的最后一部分 fdist1 FreqDist NSmyText vocab fdist1 keys vocab 200 但是当我在 vocab 20
  • Pickle:类型错误:需要类似字节的对象,而不是“str”[重复]

    这个问题在这里已经有答案了 当我在 python 3 中运行以下代码时 我不断收到此错误 fname1 auth cache s username fname fname1 encode encoding utf 8 fname fname
  • 自定义图像视图android

    我的自定义视图如下所示 package com mypackage import java util ArrayList import java util List import android content Context import
  • 以数组形式返回 group_concat 数据

    我想返回使用 group concat 作为数据数组从数据库检索的值 是否可以在 mysql 查询中执行此操作 或者我需要将数据分解成数组吗 GROUP CONCAT sh hold id as holds 返回这个 holds gt 3
  • 为什么从对象继承在 Python 中会有所不同? [复制]

    这个问题在这里已经有答案了 当类从无继承时 我有一个实例类型的对象 gt gt gt class A pass gt gt gt a A gt gt gt type a
  • 将 AVAssetWriter 与原始 NAL 单元结合使用

    我在 iOS 文档中注意到AVAssetWriterInput你可以通过nil为了outputSettings字典来指定输入数据不应重新编码 用于对附加到输出的媒体进行编码的设置 传递 nil 来指定不应重新编码附加的样本 我想利用此功能来
  • 如何为TableView创建NSIndexPath

    我需要在我定义的函数中删除表的第 1 行 为了使用deleteRowAtIndexPath你必须使用一个IndexPath定义了部分和行 如何创建这样的索引路径 以 int 1 作为唯一成员的数组将会崩溃 NSLog 消息指出该部分也需要定
  • pandas 按日期和年份分组并汇总金额

    我有这样的熊猫数据框 d dollar amount 200 25 350 00 120 00 400 50 1231 25 700 00 350 00 200 25 2340 00 date 22 01 2010 22 01 2010 2
  • 调试时如何跳出while循环

    在 Eclipse 中调试期间 我的代码进入了 while 循环 我不想循环直到满足条件 所以请告诉我如何在调试期间退出 while 循环 我看到 F7 在调试菜单下被禁用 请参阅此处的屏幕截图 You can select the lin
  • javascript 函数 btoa 的 C# 版本

    我需要将一些内容从 js 重新编码为 c 利用 js 中的 btoa 方法对一串 unicode 字符将它们转换为 base64 但是 据我所知 javascrpt 使用的编码与 c 中可用的所有编码不同 我需要编码完全相同 并且不会在这些
  • 如何在perl中验证数字?

    我知道有一个图书馆可以做到这一点 使用 Scalar Util qw looks like number 但我想使用 perl 正则表达式来做到这一点 我希望它适用于双数 而不仅仅是整数 所以我想要比这更好的东西 var d thanks
  • 从 OKHTTP 下载二进制文件

    我在我的 Android 应用程序中使用 OKHTTP 客户端进行网络连接 This https stackoverflow com questions 25367888 upload binary file with okhttp fro