多线程下载文件

来源:互联网 发布:淘宝限时秒杀11元 编辑:程序博客网 时间:2024/05/29 10:49

最近看了下多线程下载文件,下载总结一下。

原理:

1.首先访问服务器端,获取到需要下载文件的总大小,并在本地创建同样大小的空白文件;这一步很简单,用你熟悉的任何一种网络访问方法,访问服务器都可以,请求成功后获取内容长度,之后利用RandomAccessFile这个类,创建空白文件,把内容长度设置为文件大小。

2.等分任务,计算出每个线程的开始下载位置以及结束下载位置;根据步骤1中获取到的文件长度,除上想要开启的线程总数,求得的整数为每个线程的下载任务大小blockSize,开始下载位置=i*blockSize(i从0开始),停止下载位置=(i+1)*blockSize-1.



3.开启多个线程,为每个线程设置开始下载的位置以及结束下载位置;这一步就开始请求服务器进行真正的文件下载了,需要注意的就是要设置网络请求时的开始位置和停止位置setRequestProperty("Range", "bytes="+startIndext+"-"+endIndext);,responsecode不是200而是206,之后还是利用RandomAccessFile类的seek方法设置文件写入的位置,write方法进行文件的写入。


代码:

package com.example.multhread;import android.app.Activity;import android.os.Environment;import android.util.Log;import android.widget.Toast;import java.io.File;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;/** * Created by pactera on 2017/2/4. */public class DownloadManager {    private static final String path = "http://10.5.92.12:8080/loginProject/gg.exe";    private static final String TAG = "DownloadManager";    private static final int ThreadSize = 3;    private Activity activity;    private List<MyThread> threads;    public DownloadManager(Activity activity) {        this.activity = activity;        threads = new ArrayList<MyThread>();    }    public void StartDownload () {        //1.在Android客户端首先创建一个和需要下载的文件相同大小的空白文件        long fileSize = getFileSize();        //2.开启3个线程去下载对应文件        if (fileSize > 0) {            startMutileThread(fileSize);            //3.如果所有线程都下载完毕,服务器的资源就下载完毕了            ifDownLoadSuccess();        } else {            ToastOnScreen("服务器访问异常,请稍后再试");        }    }    private long getFileSize() {        try {            URL url = new URL(path);            HttpURLConnection con = (HttpURLConnection) url.openConnection();            con.setRequestMethod("GET");            con.setConnectTimeout(5000);            int code = con.getResponseCode();            if (code == 200) {                long size = con.getContentLength();//获取文件长度                Log.d(TAG,"文件大小为:"+size);                File f = new File(Environment.getExternalStorageDirectory(),"gg.exe");                RandomAccessFile file = new RandomAccessFile(f,"rwd");//在本地创建文件                file.setLength(size);//将要下载的文件长度,赋给本地文件                file.close();                return size;            }        } catch (Exception e) {            e.printStackTrace();        }        return 0;    }    private void startMutileThread(long fileSize) {        long size = fileSize/ThreadSize;//获取每个线程需要下载文件的长度        for (int i=0; i<ThreadSize; i++) {            long startIndex = i*size;//计算每个线程开始下载文件的位置            long endIndex = (i+1)*size-1;//停止下载文件的位置            if (i==ThreadSize-1) {//如果是最后一个线程,则直接下载完剩余的文件                endIndex = fileSize-1;            }            MyThread thread = new MyThread(startIndex,endIndex);//开启线程            threads.add(thread);            thread.start();        }    }    private class MyThread extends Thread {        private long startIndex;        private long endIndex;        public MyThread(long startIndex, long endIndex) {            this.startIndex = startIndex;//开始下载的位置            this.endIndex = endIndex;//停止下载的位置            Log.d(TAG,startIndex+"-"+endIndex+"部分文件开始下载!");        }        @Override        public void run() {            super.run();            try {                URL url = new URL(path);                HttpURLConnection con = (HttpURLConnection) url.openConnection();                con.setRequestMethod("GET");                con.setRequestProperty("Range","bytes="+startIndex+"-"+endIndex);//设置请求头,设置开始下载位置和停止位置                con.setConnectTimeout(5000);                int code = con.getResponseCode();                if (code == 206) {//分段下载的返回码是206不是200                    InputStream is = con.getInputStream();                    File f = new File(Environment.getExternalStorageDirectory(),"gg.exe");                    RandomAccessFile file = new RandomAccessFile(f,"rw");//在本地创建文件                    file.seek(startIndex);                    int len;                    byte[] buffer = new byte[1024];                    while ((len = is.read(buffer)) != -1) {                        file.write(buffer,0,len);                    }                    is.close();                    file.close();                    Log.d(TAG,startIndex+"-"+endIndex+"部分文件下载完毕!");                }            } catch (Exception e) {                e.printStackTrace();            }        }    }    private void ifDownLoadSuccess() {        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(2000);                    int closeThread = 0;                    for (MyThread t:threads) {                        if (!t.isAlive()) {                            closeThread++;                        }                    }                    if (closeThread == ThreadSize) {                        ToastOnScreen("下载完成");                    }                } catch (Exception e) {                    e.printStackTrace();                }            }        }).start();    }    private void ToastOnScreen(final String s) {        activity.runOnUiThread(new Runnable() {            @Override            public void run() {                Toast.makeText(activity, s, Toast.LENGTH_LONG).show();            }        });    }}


0 0
原创粉丝点击