android 多线程断点续传下载工具类
package cn.lei.util;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import android.app.ProgressDialog;import android.os.Environment;import android.widget.ProgressBar;public class DownloadUtil {private String path;private int threadnumber;private String target;private int process=0;private int totalsize;//标记是否停止下载private boolean isstop = false;int blocksize;File file;ProgressDialog pb;public DownloadUtil(String path, String target, int threadnumber,ProgressDialog pb) {this.path = path;this.target = target;this.threadnumber = threadnumber;this.pb= pb;}public int getProcess() {return process;}public int getTotalsize() {return totalsize;}public File startDownload() throws IOException {isstop = false;if (path == null) {return null;}//连接服务器查询文件字节数,URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(5000);conn.setRequestMethod("GET");totalsize = conn.getContentLength();//设置processbar,或者processDialog的Maxpb.setMax(totalsize);//得到下载文件名称String finame = path.substring(path.lastIndexOf("/") + 1);//在本地创建文件file = createFile(target, finame);//设置分配每个线程下载的大小if (totalsize % threadnumber == 0) {blocksize = totalsize / threadnumber;} else {blocksize = totalsize / threadnumber + 1;}//开启线程下载for (int i = 0; i < this.threadnumber; i++) {new DownloadThread(i).start();}return file;}private File createFile(String target, String finame) {//判断SDCARD是否可用File f = null;if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ f = new File(Environment.getExternalStorageDirectory(), target);if (!f.exists()) {f.mkdirs();}}else{//或者保存到ROMthrow new RuntimeException();}File ff = new File(f, finame);return ff;}public void stopDownload() {this.isstop = true;}class DownloadThread extends Thread {private int threadid;public DownloadThread(int threadid) {this.threadid = threadid;}@Overridepublic void run() {try {//已线程ID命名文件,保存下载进度信息File temp = new File(Environment.getExternalStorageDirectory(),target + threadid + ".temp");URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(5000);conn.setRequestMethod("GET");//计算将请求的开始字节,结束字节int startposition = threadid * blocksize;int endposition = (threadid + 1) * blocksize - 1;if (endposition > totalsize) {endposition = totalsize;}//如果存在之前下载文件信息,调整请求if (temp.exists()) {FileInputStream input = new FileInputStream(temp);byte[] buf = new byte;int len = input.read(buf);if (len > 0) {startposition = Integer.parseInt(new String(buf, 0, len));}input.close();}//设置请求conn.setRequestProperty("Range", "bytes=" + startposition + "-"+ endposition);//保存下载文件RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");accessFile.seek(startposition);InputStream is = conn.getInputStream();int leng = 0;byte[] buff = new byte;while ((leng = is.read(buff)) > 0) {if (isstop) {return;}accessFile.write(buff, 0, leng);startposition += leng;//更新process* 的信息synchronized (DownloadUtil.this) {process += leng;pb.setProgress(process);pb.setMessage(process+"/"+totalsize);}//保存下载进度FileOutputStream fos = new FileOutputStream(temp);fos.write((startposition + "").getBytes());fos.flush();fos.close();}is.close();accessFile.close();temp.delete();} catch (Exception e) {e.printStackTrace();}}} } 期待更好的算法,更好的效率的做法.这个保存进度的时候会频繁I/O操作,效率肯定不好.
下载大文件的时候,出现过下载进度不增加的情况.
对于较小的文件<8M,这个足以应付.
页:
[1]