当前位置: 代码迷 >> Android >> android 多线程断点续传上载工具类
  详细解决方案

android 多线程断点续传上载工具类

热度:12   发布时间:2016-05-01 17:28:06.0
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的Max		pb.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{//			或者保存到ROM			throw 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;		}		@Override		public 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[8];					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[1024];				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,这个足以应付.

  相关解决方案