package Homework;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.text.DecimalFormat;
public class FileDownload extends Thread {
private String Address;
private File Targetfile;
private static long TotalFilelength;
private long start;
private long end;
private boolean isExit = false;
private String flag;
private int i;
public FileDownload(String address, File targetfile, long start, long end, String flag, int i) {
this.Address = address;
this.Targetfile = targetfile;
this.start = start;
this.end = end;
this.flag = flag;
this.i = i;
}
public FileDownload(File targetfile, String flag) {
this.Targetfile = targetfile;
this.flag = flag;
}
@Override
public void run() {
switch (flag) {
case "下载":
try {
download(i);
} catch (IOException e) {
e.printStackTrace();
}
break;
case "进度":
progress();
break;
}
}
//下载文件
public void download(int i) throws IOException {
URL url = new URL(Address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(10000);
int code = conn.getResponseCode();
if (code == HttpURLConnection.HTTP_OK) {
int length = 0;
int count = 0;
long position = start;
BufferedInputStream bis = null;
RandomAccessFile bos = null;
InputStream is = conn.getInputStream();
bis = new BufferedInputStream(is);
bos = new RandomAccessFile(Targetfile, "rw");
byte[] b = new byte[1024];
position = readPosition(i);
bis.skip(position);
bos.seek(position);
while ((length = bis.read(b)) != -1 && position <= end) {
position += length;
bos.write(b, 0, length);
count++;
writePosition(position, i);
try {
sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bos.close();
bis.close();
}
}
//文件下载进度
public void progress() {
RandomAccessFile raf_read = null;
while (!isExit) {
try {
DecimalFormat df = new DecimalFormat("##.##%");
raf_read = new RandomAccessFile(Targetfile, "r");
long length = raf_read.length();
System.out.println("进度:" + df.format(length / (TotalFilelength * 1.0)));
if (length == TotalFilelength) {
isExit = true;
}
try {
sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (raf_read != null)
try {
raf_read.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 实时记录文件拷贝(下载)到的目标位置
* @param position
* @param dir
*/
public void writePosition(long position, int i){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(new File("C:\\Users\\swj\\Desktop\\temp.txt"),"rw");
raf.seek(i * 8);
raf.writeLong(position);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(raf != null)raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取记录长度的文件中文件指针的位置
* @param dir
* @return
*/
public long readPosition(int i){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(new File("C:\\Users\\swj\\Desktop\\temp.txt"), "r");
raf.seek(i * 8);
return raf.readLong();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(raf != null)raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return 0L;
}
public static void main(String[] args) throws IOException {
String address = "http://192.168.46.254:8888/easyBuy/images/plmm.jpg";
URL url = new URL(address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(10000);
TotalFilelength = conn.getContentLength();
long len1 = TotalFilelength / 4;
long len2 = TotalFilelength / 2;
long len3 = TotalFilelength / 4 * 3;
long len4 = TotalFilelength;
File targetfile = new File("C:\\Users\\swj\\Desktop", address.substring(address.lastIndexOf("/")));
new FileDownload(address, targetfile, 0, len1, "下载", 0).start();
new FileDownload(address, targetfile, len1, len2, "下载", 1).start();
new FileDownload(address, targetfile, len2, len3, "下载", 2).start();
new FileDownload(address, targetfile, len3, len4, "下载", 3).start();
new FileDownload(targetfile, "进度").start();
}
}
本程序一共有5个线程:4个下载线程,1个进度显示线程。4个下载线程的各个起始位置跟结束位置不同,所以能实现分段下载。然后1个进度显示线程是一直读取文件大小并将其与文件总长度做比较然后就能显示出已下载的百分比。
本程序为一个初出茅庐的小程序猿写的,大致功能都实现了但是还是有很多问题跟错误,希望大家指出并私信给我。