美文网首页
Http断点续传要点

Http断点续传要点

作者: SDY_0656 | 来源:发表于2017-09-26 16:41 被阅读0次

在http断点续传的过程中,主要有以下几个方面要注意:
1,新建一个temp文件,记录断点的位置,也就是上次下载的数量。
2,采用RandomAccessFile来进行文件读写,RandomAccessFile相当于是一个文件输入输出流的结合。提供了一些在文件中操作位置的方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。

断点续传的步骤主要是以下几点:
1,判断temp文件是否存在,存在就读取进度,不存在就创建一个新的。
2,将读取的进度写入请求头重,就是设置请求的范围,例如:
HttpUrlConnection中是如下设置:
conn.setRequestProperty("Range", "bytes=" + lastPostion + "-" + endposition);

OKHttp设置在Header中:
builder.addHeader("RANGE", "bytes=" + startIndex + "-" + (contentLength - 1));
3,写入APK文件的时候,同时将进度写入temp文件。完成的时候删除temp文件,以及关闭RandomAccessFile。

while ((len = is.read(buffer)) != -1) {
                    randomAccessFile.write(buffer, 0, len);//写入APK
                    downloadLength += len;
                    downloadInfo.setProgress(downloadLength);
                    cacheFile.seek(0);
                    cacheFile.write(String.valueOf(downloadLength).getBytes());  //记录进度
                }

下面是一个完整实例:

public static class newThreadDown extends Thread {
    private String urlstr;
    private long lastPostion;
    private long endposition;
    public newThreadDown(String urlstr, long endposition) {
        this.urlstr = urlstr;
        this.endposition = endposition;
    }

    @Override
    public void run() {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(urlstr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10 * 1000);
            conn.setRequestMethod("GET");
            conn.setReadTimeout(10 * 1000);
            long startposition = 0;
            // 创建记录缓存文件
            File tempfile = new File("e:\\" + 1 + ".txt");
            if (tempfile.exists()) {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(tempfile));
                BufferedReader br = new BufferedReader(isr);
                String lastStr = br.readLine();
                lastPostion = Integer.parseInt(lastStr);
                conn.setRequestProperty("Range", "bytes=" + lastPostion + "-" + endposition);
                br.close();
            } else {
                tempFile.createNewFile();
                lastPostion = startposition;
                conn.setRequestProperty("Range", "bytes=" + lastPostion + "-" + endposition);
            }

            if (conn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
                System.out.println(206 + "请求成功");
                InputStream is = conn.getInputStream();
                RandomAccessFile accessFile = new RandomAccessFile(new File("e:\\" + path.substring(path.lastIndexOf("/") + 1)),
                        "rwd");
                accessFile.seek(lastPostion);
                randomAccessFile.seek(startIndex);
                RandomAccessFile cacheFile = new RandomAccessFile(tempFile, "rwd");
                System.out.println("开始位置" + lastPostion);
                byte[] bt = new byte[1024 * 200];
                int len = 0;
                long total = 0;
                while ((len = is.read(bt)) != -1) {
                    total += len;
                    accessFile.write(bt, 0, len);
                    long currentposition = startposition + total;
                    cacheFile.seek(0);
                    rf.write(String.valueOf(currentposition).getBytes());
                    rf.close();
                }
                System.out.println("下载完毕");
                is.close();
                accessFile.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.run();
    }
}

以上实现的是单线程下载,当要实现多线程下载的时候,做如下改进:
1,对下载的文件进行分块,每个线程负责不同区块的下载,主要设置为设置下载的请求范围,设置文件的写入范围:

conn.setRequestProperty("Range", "bytes=" + dEntity.startLocation + "-" + dEntity.endLocation);
//创建可设置位置的文件
                RandomAccessFile file = new RandomAccessFile(dEntity.tempFile, "rwd");
                //设置每条线程写入文件的位置
                file.seek(dEntity.startLocation);

2,对每个线程的tempFile多加一个字段,判断该线程是否下载完,当所有线程都下载完的时候,才是整体下载完成。
参考文章:http://www.jianshu.com/p/5b2e22c42467, 修正了原文中存在的BUG。

相关文章

  • Http断点续传要点

    在http断点续传的过程中,主要有以下几个方面要注意:1,新建一个temp文件,记录断点的位置,也就是上次下载的数...

  • ios 后台下载,断点续传总结

    断点续传 demo 断点续传的原理是在HTTP1.1协议(RFC2616)中定义了断点续传相关的HTTP头的Ran...

  • HTTP1.0和1.1的区别

    HTTP1.0HTTP1.1短连接长连接不支持断点续传支持断点续传添加了更多缓存控制策略添加了更多错误响应代码以I...

  • 多线程下载,断点续传技术要点---Http Header

    涉及到的Header Accept-Ranges Range If-Range Content-Range Acc...

  • Http相关

    *Unity中Http访问和下载*Unity中Http的优化*HTTP断点续传相关概念**简书:Unity发送HT...

  • AFN断点续传机制

    AFN断点续传机制 检查服务器文件信息 检查本地文件 如果比服务器文件小,断点续传,利用HTTP请求头的Range...

  • 01要求技术点

    关于网络 1.你对 http 协议chunk 协议如何断点续传分片上传 ssl 握手? http://blog.c...

  • Android Okhttp 断点续传

    1 Http 断点续传知识点 1.1 什么是断点续传 指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为...

  • HTTP协议断点续传

    HTTP协议从V1.1开始可以使用长链接和断点续传和其他新特性,断点续传也就是从下载中断的分块,重新进行下载,直到...

  • JAVA多线程下载,断点续传(HTTP)

    HTTP的断点续传其实很简单,就是通过设置Header (RANGE: bytes=XXXXXXXX- ) 1, ...

网友评论

      本文标题:Http断点续传要点

      本文链接:https://www.haomeiwen.com/subject/cposextx.html