广告
返回顶部
首页 > 资讯 > 移动开发 >Android(Java)下载断点续传的实现
  • 165
分享到

Android(Java)下载断点续传的实现

JAVA断点续传断点Android 2022-06-06 14:06:05 165人浏览 泡泡鱼
摘要

Android(Java)下载断点续传的实现一、要注意的地方1. 追加文件2. 跳过输入流3.range header坑点1.坑点2坑点3.二、

Android(Java)下载断点续传的实现一、要注意的地方1. 追加文件2. 跳过输入流3.range header坑点1.坑点2坑点3.二、代码方法1方法2

最近在做一个下载文件的功能的时候,因为要支持断点续传,虽然整体上思路很清晰,也比较简单,但是在做的过程中还是遇到了几个坑,特意在此记录一下,也重新梳理下下载断点续传的实现过程。

一、要注意的地方

这里先把几个坑点先说明一下:

1. 追加文件

如果你写入文件用的是FileOutputStream,那么一定要用两参的构造方法:

```java
new FileOutputStream(file,true); // 第二个参数为true
```
2. 跳过输入流

当你用方法1(通过inputStream的skip)去实现断点续传的时候,skip方法有坑,简单来说就是skip方法不能保证一定会跳过你指定的字节数,所以你自己要做一个简单处理:

private void skip(InputStream in, long offset) throws ioException {
        long skip = 0;
        do {
            offset -= skip;
            skip = in.skip(offset);
            if (skip <= 0) {
                break;
            }
        } while (skip != offset);
    }
3.range header

当你用方法2(Http range header)去实现断点续传的时候,有如下三个坑:

坑点1.

首先要确保服务器支持断点续传,我当时就是因为从网上先随便找个文件来下载,一些文件的服务器是不支持的,导致我调试了好久好久。。。那么怎么判断服务器是否支持呢? 当然是问服务器的同学啦,如果他们也不确定的话(又一个坑~),求人不如求己,可以通过如下命令查看:

curl -i --range 100-200 http://app.znds.com/down/20200331/w2zry_1.53.1.6_dangbei.apk

看它返回的数据

HTTP/1.1 206 Partial Content
Server: jsP3/2.0.14
Date: Fri, 24 Apr 2020 04:21:54 GMT
Content-Type: application/vnd.android.package-arcHive
Content-Length: 101
Connection: keep-alive
ETag: "7629026C24EBCA9B219A6BEC4DA7E475"
Last-Modified: Tue, 31 Mar 2020 08:02:33 GMT
Age: 863675
Content-Range: bytes 100-200/393647401
Accept-Ranges: bytes
x-oss-request-id: 5E82FA10146F3833363BA5BA
x-oss-object-type: NORMal
x-oss-hash-crc64ecma: 14417895789503488492
x-oss-storage-class: Standard
Content-MD5: dikCbCTrypshmmvsTafkdQ==
x-oss-server-time: 9
Ohc-File-Size: 393647401
Timing-Allow-Origin: *
Ohc-Cache-HIT: cangzuncache63 [4], qdix131 [3]

如果也Content-Range 和 Accept-Ranges,那说明支持,否则就别费劲了,用方法1吧。

坑点2

第二个坑点是,给request设置header的时候,代码如下:

header("Range", "bytes=" + offset + "-")

一定不能缺少最后的那个"-",否则这个就是个无效的header。

坑点3.

第三个坑点是,当你给你的request添加了这个header之后,你要计算下载百分比吧,我之前计算百分比的分母(即文件大小)的时候,用的是Content-length里返回的数据,那么问题就来了,当你断点续传的时候,返回的数据流里不是所有数据的大小,所以content-length肯定就变小了,这时你在计算百分比肯定就错误了(好吧,这是我自己的问题),解决办法有两个,第一个还是每次都取content-length,但是不能直接用来做分母,要和本地文件的大小做一个加和;第二个就是服务器直接在反水的数据里告诉你文件大小,不取content-length。

二、代码

这里我还用了OKhttp做网络请求。
下面两种方法我都是自己传进来了文件的大小,如果不想自己传的话,下面的size可以改成,contentLength自己去获取吧。

long size = contentLength + offset;
方法1

优点:不依赖服务器的支持,完全端上自己实现;
缺点:会浪费流量;

public void download(final String url, final String path, long offset,
                         long size, final OnDownloadListener listener) {
        Request request =
                new Request.Builder()
                        .url(url)
                        .build();
        downloadCall = okHttpClient.newCall(request);
        downloadCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                listener.onDownloadFailed(1);
            }
            @Override
            public void onResponse(Call call, Response response) {
                listener.onDownloadStart();
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();
                    // 跳过offset文件大小
                    skip(is,offset);
                    File file = new File(path);
                    fos = new FileOutputStream(file, true);
                    long sum = offset;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        Log.d("downloadtUtil", "download length:" + sum);
                        int progress = (int) (sum * 1.0f / size * 100);
                        // 下载中
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成
                    listener.onDownloadSuccess();
                } catch (SocketException e) {
                    e.printStackTrace();
                    listener.onDownloadFailed(1);
                } catch (IOException e) {
                    e.printStackTrace();
                    listener.onDownloadFailed(0);
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                    }
                }
            }
        });
    }
方法2

优点:节省流量,已经下载过的数据不再下载了,真正的断点续传;
缺点:依赖服务器配置或者服务器开发人员开发;

public void download(final String url, final String path, long offset,
                         long size, final OnDownloadListener listener) {
        Request request =
                new Request.Builder()
                        .header("Range", "bytes=" + offset + "-")
                        .url(url)
                        .build();
        downloadCall = okHttpClient.newCall(request);
        downloadCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                listener.onDownloadFailed(1);
            }
            @Override
            public void onResponse(Call call, Response response) {
                HLog.d("http request:" + response.request().headers());
                HLog.d("http request:" + response.headers());
                listener.onDownloadStart();
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                try {
                    is = response.body().byteStream();
                    File file = new File(path);
                    fos = new FileOutputStream(file, true);
                    long sum = offset;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        Log.d("downloadtUtil", "download length:" + sum);
                        int progress = (int) (sum * 1.0f / size * 100);
                        // 下载中
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成
                    listener.onDownloadSuccess();
                } catch (SocketException e) {
                    e.printStackTrace();
                    listener.onDownloadFailed(1);
                } catch (IOException e) {
                    e.printStackTrace();
                    listener.onDownloadFailed(0);
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

作者:宇光十色_FLY


--结束END--

本文标题: Android(Java)下载断点续传的实现

本文链接: https://www.lsjlt.com/news/29678.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android(Java)下载断点续传的实现
    Android(Java)下载断点续传的实现一、要注意的地方1. 追加文件2. 跳过输入流3.range header坑点1.坑点2坑点3.二、...
    99+
    2022-06-06
    JAVA 断点续传 断点 Android
  • Java实现多线程下载和断点续传
    java的多线程下载能够明显提升下载的速度,平时我们用的迅雷软件之所以能够下载那么快,就是使用了多线程;当用户在下载的过程中,有断电或断网的可能,当用户再次点击下载时,应该让用户接着...
    99+
    2022-11-13
  • php怎么实现下载断点续传
    本教程操作环境:windows7系统、PHP8.1版、Dell G3电脑。php怎么实现下载断点续传?PHP实现文件下载,支持断点续传我一般废话比较少,直接甩代码,不懂扣我,再不懂就只能扣脚丫了,OK?PHP实现文件下载接口,支持断点续传,...
    99+
    2022-11-06
  • php如何实现下载断点续传
    本篇内容介绍了“php如何实现下载断点续传”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php实现下载断点续传的方法:1、创建一个php示例...
    99+
    2023-07-04
  • Android通过HTTP协议实现断点续传下载实例
    整理文档,搜刮出一个Android通过HTTP协议实现断点续传下载的代码,稍微整理精简一下做下分享。 FileDownloader.java   ...
    99+
    2022-06-06
    HTTP 断点续传 断点 http协议 Android
  • Android实现网络多线程断点续传下载实例
    我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件非常简单的事。那么,多线程断点需要什么功能? 1.多线程下载, ...
    99+
    2022-06-06
    多线程 断点续传 断点 线程 Android
  • Android实现网络多线程断点续传下载功能
    我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件非常简单的事。那么,多线程断点需要什么功能? 1.多线程下载 2...
    99+
    2022-06-06
    多线程 断点续传 断点 线程 Android
  • Android多线程断点续传下载功能实现代码
    原理 其实断点续传的原理很简单,从字面上理解,所谓断点续传就是从停止的地方重新下载。 断点:线程停止的位置。 续传:从停止的位置重新下载。 用代码解析就是: 断点:当...
    99+
    2022-06-06
    android多线程 断点续传 断点 线程 Android
  • iOS使用NSURLConnection实现断点续传下载
    本文实例为大家分享了iOS使用NSURLConnection实现断点续传下载的具体代码,供大家参考,具体内容如下 一.断点续传的原理 断点续传的原理:每次在想服务器请求下载数据的同时...
    99+
    2022-11-13
  • python 文件下载之断点续传的实现
    目录1.前序2.技术原理2.1 Content-Range2.2 Range3. 代码实现1.前序 当下载突然断开后,断点续传就需要了,继续前面下载的内容下载。解决了不需要重复下载 ...
    99+
    2022-11-12
  • android使用OkHttp实现下载的进度监听和断点续传
    1. 导入依赖包 // retrofit, 基于Okhttp,考虑到项目中经常会用到retrofit,就导入这个了。 compile 'com.squareup.retr...
    99+
    2022-06-06
    okhttp 监听 断点续传 断点 Android
  • C#怎样实现文件下载断点续传
    目录前言文件下载-服务端使用a标签提供文件下载使用Response.TransmitFile提供文件下载其他方式文件下载文件下载-客户端直接下载异步下载断点续传断点续传(服务端的支持...
    99+
    2022-11-12
  • Android实现断点续传功能
    本文实例为大家分享了Android实现断点续传的具体代码,供大家参考,具体内容如下 断点续传功能,在文件上传中断时,下次上传同一文件时,能在上次的断点处继续上传,可节省时间和流量 总...
    99+
    2022-11-13
  • 详解Android使用OKHttp3实现下载(断点续传、显示进度)
    OKHttp3是如今非常流行的Android网络请求框架,那么如何利用Android实现断点续传呢,今天写了个Demo尝试了一下,感觉还是有点意思 准备阶段 我们会用到OK...
    99+
    2022-06-06
    okhttp 断点续传 断点 Android
  • Android编程开发实现多线程断点续传下载器实例
    本文实例讲述了Android编程开发实现多线程断点续传下载器。分享给大家供大家参考,具体如下: 使用多线程断点续传下载器在下载的时候多个线程并发可以占用服务器端更多资源,从而加...
    99+
    2022-06-06
    多线程 断点续传 断点 线程 Android
  • iOS怎么使用NSURLConnection实现断点续传下载
    本篇内容介绍了“iOS怎么使用NSURLConnection实现断点续传下载”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一.断点续传的原理...
    99+
    2023-06-30
  • Android实现多线程断点续传
    本文实例为大家分享了Android实现多线程断点续传的具体代码,供大家参考,具体内容如下 多线程下载涉及到的知识点: 1、Service的使用:我们在Service中去下载文件;2、...
    99+
    2022-11-13
  • Android应用中的断点续传下载如何利用HTTP协议实现
    这期内容当中小编将会给大家带来有关Android应用中的断点续传下载如何利用HTTP协议实现,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。FileDownloader.java    ...
    99+
    2023-05-31
    android http roi
  • Android如何实现简单断点续传和下载到本地功能
    这篇文章主要介绍了Android如何实现简单断点续传和下载到本地功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下效果展示导入依赖与权限依赖compile&nbs...
    99+
    2023-05-30
    android
  • java实现文件的断点续传
    所谓文件的断点续传,就是一个线程传输文件,另一个线程控制传输标识,以达到暂停文件效果、恢复文件上传的效果。 本demo使用最基本的线程之间的通信来实现一个简单的断点续传。 packa...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作