多线程下载文件

package com.example.x;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import android.os.Environment;
import android.util.Log;

public class Download {
/** 
     * 下载准备工作,获取SD卡路径、开启线程 
     */  
    public  void doDownload() {  
        // 获取SD卡路径  
      String path = Environment.getExternalStorageDirectory()  
                  + "/whxxbooks/";  
        File file = new File(path);  
        // 如果SD卡目录不存在创建  
        if (!file.exists()) {  
            file.mkdir();  
        }  
      
  
        // 简单起见,我先把URL和文件名称写死,其实这些都可以通过HttpHeader获取到  
//        String downloadUrl = "http://gdown.baidu.com:80/data/wisegame/91319a5a1dfae322/baidu_16785426.apk";  
//        String fileName = "baidu_16785426.apk";  
        String downloadUrl = null;
try {
downloadUrl = "http://sf.idcpub.cn:8021/"+URLEncoder.encode("epub图书/最终文本/中国史一本通.epub", "GBK");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
        String fileName = "中国史一本通.epub";  
        int threadNum = 5;  
        String filepath = path + fileName;  
        Log.d("TAG", "download file  path:" + filepath);  
        DownloadTask task = new DownloadTask(downloadUrl, threadNum, filepath);  
        task.start();  
    }
}

package com.example.x;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import android.os.Environment;
import android.util.Log;

/**
 * 多线程文件下载
 * 
 * @author yangxiaolong @2014-8-7
 */
public class DownloadTask extends Thread {
private String downloadUrl;// 下载链接地址
private int threadNum;// 开启的线程数
private String filePath;// 保存文件路径地址
private int blockSize;// 每一个线程的下载量

public DownloadTask(String downloadUrl, int threadNum, String fileptah) {
this.downloadUrl = downloadUrl;
this.threadNum = threadNum;
this.filePath = fileptah;
}

@Override
public void run() {

FileDownloadThread[] threads = new FileDownloadThread[threadNum];
try {

URL url = new URL(downloadUrl);
Log.d("TAG", "download file http path:" + downloadUrl);
URLConnection conn = url.openConnection();
// 读取下载文件总大小
int fileSize = conn.getContentLength();
if (fileSize <= 0) {
System.out.println("读取文件失败");
return;
}

// 计算每条线程下载的数据长度
blockSize = (fileSize % threadNum) == 0 ? fileSize / threadNum : fileSize / threadNum + 1;

Log.d("TAG", "fileSize:" + fileSize + "  blockSize:");

File file = new File(filePath);
for (int i = 0; i < threads.length; i++) {
// 启动线程,分别下载每个线程需要下载的部分
threads[i] = new FileDownloadThread(url, file, blockSize, (i + 1));
threads[i].setName("Thread:" + i);
threads[i].start();
}

boolean isfinished = false;
int downloadedAllSize = 0;
while (!isfinished) {
isfinished = true;
// 当前所有线程下载总量
downloadedAllSize = 0;
for (int i = 0; i < threads.length; i++) {
downloadedAllSize += threads[i].getDownloadLength();
if (!threads[i].isCompleted()) {
isfinished = false;
}
}
// 通知handler去更新视图组件
// Message msg = new Message();
// msg.getData().putInt("size", downloadedAllSize);
// mHandler.sendMessage(msg);
// Log.d(TAG, "current downloadSize:" + downloadedAllSize);
Thread.sleep(1000);// 休息1秒后再读取下载进度
}
Log.d("TAG", " all of downloadSize:" + downloadedAllSize);

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}

package com.example.x;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;

import android.util.Log;

public class FileDownloadThread extends Thread {  
  
    private static final String TAG = FileDownloadThread.class.getSimpleName();  
  
    /** 当前下载是否完成 */  
    private boolean isCompleted = false;  
    /** 当前下载文件长度 */  
    private int downloadLength = 0;  
    /** 文件保存路径 */  
    private File file;  
    /** 文件下载路径 */  
    private URL downloadUrl;  
    /** 当前下载线程ID */  
    private int threadId;  
    /** 线程下载数据长度 */  
    private int blockSize;  
  
    /** 
     *  
     * @param url:文件下载地址 
     * @param file:文件保存路径 
     * @param blocksize:下载数据长度 
     * @param threadId:线程ID 
     */  
    public FileDownloadThread(URL downloadUrl, File file, int blocksize,  
            int threadId) {  
        this.downloadUrl = downloadUrl;  
        this.file = file;  
        this.threadId = threadId;  
        this.blockSize = blocksize;  
    }  
  
    @Override  
    public void run() {  
  
        BufferedInputStream bis = null;  
        RandomAccessFile raf = null;  
  
        try {  
            URLConnection conn = downloadUrl.openConnection();  
            conn.setAllowUserInteraction(true);  
  
            int startPos = blockSize * (threadId - 1);//开始位置  
            int endPos = blockSize * threadId - 1;//结束位置  
            //设置当前线程下载的起点、终点  
            conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);  
            System.out.println(Thread.currentThread().getName() + "  bytes="  
                    + startPos + "-" + endPos);  
  
            byte[] buffer = new byte[1024];  
            bis = new BufferedInputStream(conn.getInputStream());  
  
            raf = new RandomAccessFile(file, "rwd");  
            raf.seek(startPos);  
            int len;  
            while ((len = bis.read(buffer, 0, 1024)) != -1) {  
                raf.write(buffer, 0, len);  
                downloadLength += len;  
            }  
            isCompleted = true;  
            Log.d(TAG, "current thread task has finished,all size:"  
                    + downloadLength);  
  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (bis != null) {  
                try {  
                    bis.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
            if (raf != null) {  
                try {  
                    raf.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
  
    /** 
     * 线程文件是否下载完毕 
     */  
    public boolean isCompleted() {  
        return isCompleted;  
    }  
  
    /** 
     * 线程下载文件长度 
     */  
    public int getDownloadLength() {  
        return downloadLength;  
    }  
  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春哥一号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值