`

多线程下载文件

阅读更多
(1)
public class MultiThreadDownload extends Thread {

    //定义的一些常量变量,看名字就知道什么意思了

private static final int BUFFER_SIZE = 1024;

private int blockSize;

private int threadNum = 5;

private int fileSize;

private int downloadedSize;

String urlStr, threadNo, fileName;

private String savePath;

private int downloadPercent = 0 , downloadSpeed = 0, usedTime=0;

private long startTime,curTime;

private boolean completed = false;

    //用URL,保存路径,保存名称来构造。

public MultiThreadDownload(String URL, String savePath, String fileName) {

this.urlStr = URL;

this.savePath = savePath;

this.fileName = fileName;

}



@Override

public void run() {

FileDownloadThread[] fds = new FileDownloadThread[threadNum];

try {

URL url = new URL(urlStr);

URLConnection conn = url.openConnection();

fileSize = conn.getContentLength();

blockSize = fileSize / threadNum;

File file[] = new File[threadNum];

                    //根据默认的线程数,或者自己修改设置的线程数来分块,创建分块后的文件块

for (int i = 0; i < threadNum; i++) {

file[i] = new File(savePath + fileName + ".part"

+ String.valueOf(i));

                            //将分块的文件交给每个线程处理,最后一块应该大于等于平均块,因为可能有余数

FileDownloadThread fdt = new FileDownloadThread(url, file[i], i

* blockSize, (i + 1) != threadNum ? ((i + 1)

* blockSize - 1) : fileSize);

fdt.setName("Thread" + i);

fdt.start();

fds[i] = fdt;

}

startTime = System.currentTimeMillis();

                    //获取起始下载的时间,用次来计算速度。

boolean finished = false;

while (!finished) {

downloadedSize = 0;

finished = true;

for (int i = 0; i < fds.length; i++) {

downloadedSize += fds[i].getDownloadSize();

if (!fds[i].isFinished()) {

finished = false;

}

}

                            //计算下载的百分比

downloadPercent = (downloadedSize*100)/fileSize;

                            //获取当前时间,计算平均下载速度

curTime = System.currentTimeMillis();

usedTime =(int)((curTime-startTime)/1000);

if(usedTime==0)

usedTime =1;

downloadSpeed = (downloadedSize/usedTime)/1024;

sleep(1000);

}

                   //这个是分块下载完成的标志

completed = true;

                    //进行模块整合

RandomAccessFile raf = new RandomAccessFile(savePath + fileName,

"rw");

byte[] tempbytes = new byte[BUFFER_SIZE];

InputStream in = null;

int byteread = 0;

for (int i = 0; i < threadNum; i++) {

in = new FileInputStream(file[i]);

while ((byteread = in.read(tempbytes)) != -1)

{

raf.write(tempbytes, 0, byteread);

}

                            //每次整合完一块就删除一块。

in.close();

file[i].delete();

}

raf.close();

System.out.println(getName() + " end");

} catch (Exception e) {

// TODO: handle exception

}

}

   //获取下载百分比

public int getDownloadPercent(){

return this.downloadPercent;

}

   //获取下载速度

public int getDownloadSpeed(){

return this.downloadSpeed;

}

   //修改默认线程数

public void setThreadNum(int threadNum){

this.threadNum = threadNum;

}

    //分块下载完成的标志

public boolean isCompleted(){

return this.completed;

}

}

(2)
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, File file, int startPosition,
int endPosition) {
this.url = url;
this.file = file;
this.startPosition = startPosition;
this.curPosition = startPosition;
this.endPosition = endPosition;
}
public void run() {
BufferedInputStream bis = null;
RandomAccessFile fos = null;
byte[] buf = new byte[BUFFER_SIZE];
URLConnection con = null;
try {
//打开URL连接
con = url.openConnection();
con.setAllowUserInteraction(true);
//判断是否该文件存在,如果存在且下载完成,直接返回。
if ((file.length() + startPosition) == endPosition) {
this.finished = true;
}
//文件未下载完成,获取到当前指针位置,继续下载。
else {
con.setRequestProperty("Range", "bytes="
+ (startPosition + file.length()) + "-" + endPosition);
fos = new RandomAccessFile(file, "rw");
fos.seek(file.length());
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;
}
}
this.finished = true;
bis.close();
fos.close();
}
} catch (IOException e) {
System.out.println(getName() + " Error:" + e.getMessage());
}
}
public boolean isFinished() {
return finished;
}
public int getDownloadSize() {
return downloadSize;
}
}
(3)DownActivity
public class DownActivity extends Activity {
private String url="http://download.eoemarket.com/app?id=9449&client_id=114&channel_id=115";
private String savepath="/sdcard/";
private String savename="downfile.apk";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);
MultiThreadDownload down=new MultiThreadDownload(url,savepath,savename);
down.start();

}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics