多线程下载文件

来源:互联网 发布:九州通i9软件 编辑:程序博客网 时间:2024/05/21 06:37

import java.io.File;import java.net.URL;import java.net.URLConnection;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;importandroid.widget.Button;import android.widget.EditText;import android.widget.ProgressBar;importandroid.widget.TextView;public class FileDownloadDemo extends Activity {private EditTextdownloadUrl;private EditTextdownloadFileName;private EditTextdownloadThreadNum;private ButtondownloadBt;private ProgressBardownloadProgressBar;private TextViewprogressMessage;private int downloadedSize = 0;private int fileSize = 0;@Overridepublic void onCreate(BundlesavedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);downloadUrl =(EditText) findViewById(R.id.downloadUrl);downloadFileName = (EditText)findViewById(R.id.downloadFileName);downloadThreadNum = (EditText)findViewById(R.id.downloadThreadNum);progressMessage =(TextView)findViewById(R.id.progressMessage);downloadBt =(Button)findViewById(R.id.downloadBt);downloadProgressBar = (ProgressBar)findViewById(R.id.downloadProgressBar);downloadProgressBar.setVisibility(View.VISIBLE);downloadProgressBar.setMax(100);downloadProgressBar.setProgress(0);downloadBt.setOnClickListener(new OnClickListener(){public void onClick(View v){download();}});}private void download() {// 获取SD卡目录String dowloadDir = Environment.getExternalStorageDirectory()+ "/ideasdownload/";File file = new File(dowloadDir);//创建下载目录if (!file.exists()){file.mkdirs();}//读取下载线程数,如果为空,则单线程下载int downloadTN = Integer.valueOf("".equals(downloadThreadNum.getText().toString()) ?"1" :downloadThreadNum.getText().toString());//如果下载文件名为空则获取Url尾为文件名int fileNameStart = downloadUrl.getText().toString().lastIndexOf("/");String fileName ="".equals(downloadFileName.getText().toString())? downloadUrl.getText().toString().substring(fileNameStart): downloadFileName.getText().toString();//开始下载前把下载按钮设置为不可用downloadBt.setClickable(false);//进度条设为0downloadProgressBar.setProgress(0);//启动文件下载线程new downloadTask(downloadUrl.getText().toString(),Integer.valueOf(downloadTN), dowloadDir + fileName).start();}Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {//当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息int progress = (Double.valueOf((downloadedSize* 1.0 /fileSize * 100))).intValue();if (progress == 100) {downloadBt.setClickable(true);progressMessage.setText("下载完成!");} else{progressMessage.setText("当前进度:"+ progress + "%");}downloadProgressBar.setProgress(progress);}};public class downloadTask extends Thread {private int blockSize,downloadSizeMore;private int threadNum = 5;String urlStr, threadNo, fileName;public downloadTask(String urlStr, int threadNum, StringfileName) {this.urlStr = urlStr;this.threadNum = threadNum;this.fileName = fileName;}@Overridepublic void run() {FileDownloadThread[] fds = new FileDownloadThread[threadNum];try {URL url = new URL(urlStr);URLConnection conn = url.openConnection();//获取下载文件的总大小fileSize =conn.getContentLength();//计算每个线程要下载的数据量blockSize = fileSize / threadNum;// 解决整除后百分比计算误差downloadSizeMore =(fileSize % threadNum);File file = new File(fileName);for (inti = 0; i< threadNum; i++) {//启动线程,分别下载自己需要下载的部分FileDownloadThread fdt =new FileDownloadThread(url, file,i * blockSize, (i + 1)* blockSize - 1);fdt.setName("Thread"+ i);fdt.start();fds =fdt;}boolean finished = false;while (!finished) {// 先把整除的余数搞定downloadedSize =downloadSizeMore;finished = true;for (inti = 0; i< fds.length; i++) {downloadedSize +=fds.getDownloadSize();if (!fds.isFinished()){finished = false;}}//通知handler去更新视图组件handler.sendEmptyMessage(0);//休息1秒后再读取下载进度sleep(1000);}} catch(Exception e) {}}}}

//Java代码:import java.io.BufferedInputStream;importjava.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.net.URL;import java.net.URLConnection;importandroid.util.Log;public class FileDownloadThread extends Thread{private static final int BUFFER_SIZE=1024;private URL url;private File file;private int startPosition;private int endPosition;private int curPosition;//用于标识当前线程是否下载完成private boolean finished=false;private int downloadSize=0;public FileDownloadThread(URL url,Filefile,int startPosition,int endPosition){this.url=url;this.file=file;this.startPosition=startPosition;this.curPosition=startPosition;this.endPosition=endPosition;}@Overridepublic void run() {BufferedInputStream bis = null;RandomAccessFile fos =null; byte[] buf = newbyte[BUFFER_SIZE];URLConnection con =null;try {con =url.openConnection();con.setAllowUserInteraction(true);//设置当前线程下载的起点,终点con.setRequestProperty("Range","bytes="+ startPosition + "-"+ endPosition);//使用java中的RandomAccessFile对文件进行随机读写操作fos = new RandomAccessFile(file, "rw");//设置开始写文件的位置fos.seek(startPosition);bis = new BufferedInputStream(con.getInputStream()); //开始循环以流的形式读写文件while (curPosition < endPosition) {int len =bis.read(buf, 0,BUFFER_SIZE); if (len ==-1) {break;}fos.write(buf, 0, len);curPosition =curPosition + len;if (curPosition > endPosition) {downloadSize+=len- (curPosition - endPosition) + 1;} else{downloadSize+=len;}}//下载完成设为truethis.finished = true;bis.close();fos.close();} catch(IOException e) {Log.d(getName() +"Error:",e.getMessage());}}public boolean isFinished(){return finished;}public int getDownloadSize(){return downloadSize;}}



原创粉丝点击