java多线程下载
URL(Uniform Resource Locator):代表 统一资源定位器。指向互联网“资源”的指针,资源可以是目录和文件,也可以是复杂的对象引用(如数据库或者搜索引擎)。
URL由协议名,主机,端口,资源组成。
protocal://host:port/resourceName
如: https://www.baidu.com/ www.baidu.com == 220.181.112.244
资源(一张照片):http://www.crazyit.org/data/attachment/album/201805/10/103528r04u4m2m01qec0oy.jpg
URL实例的一些方法
- String getFile : 获取URL的资源名。
- String getHost : 获取URL的主机名。
- Sting getPath: 获取URL的路径部分。
- int getPort :获取端口号。
- String getProtocol:获取URL协议名称。
- String getQuery:获取该URL的字符串查询部分。
- URLConnection openConnection() :返回一个URLConnection对象,他代表与URL所引用的远程对象的链接。
- InputStream openStream() : 打开与此URL的链接,并返回一个用于读取该URL资源的输入流。
下面是一个简单的多线程(没有实现断点下载)下载:
package networkProgramming;
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;
public class DownUtil {
private String path;
private String targetFile;
private int fileSize;
private int threadNum;
private DownThread[] threads;
public DownUtil(String path , String targetFile , int threadNum)
{
this.path = path;
this.targetFile = targetFile;
this.threadNum = threadNum;
threads = new DownThread[threadNum];
}
public void downLoad() throws IOException {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
//接受全部类型的资源
conn.setRequestProperty("Accept" , "*/*");
fileSize = conn.getContentLength();
conn.disconnect();
RandomAccessFile file = new RandomAccessFile(targetFile , "rw");
file.setLength(fileSize);
file.close();
int currentPartSize = fileSize / threadNum + 1;
for (int i = 0; i < threadNum; i++) {
int startPos = i * currentPartSize;
RandomAccessFile currentPart = new RandomAccessFile(targetFile , "rw");
currentPart.seek(startPos);
threads[i] = new DownThread(startPos , currentPartSize , currentPart);
threads[i].start();
}
}
private class DownThread extends Thread
{
private int startPos;
private int currentPartSize;
public int length = 0;
private RandomAccessFile currentPart;
public DownThread(int startPos , int currentPartSize , RandomAccessFile currentPart)
{
this.startPos = startPos;
this.currentPartSize = currentPartSize;
this.currentPart = currentPart;
}
@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept" , "*/*");
InputStream inputStream = conn.getInputStream();
inputStream.skip(startPos);
byte[] bytes = new byte[1024];
int hasRead;
while(length < currentPartSize && (hasRead = inputStream.read(bytes)) !=-1)
{
length += hasRead;
currentPart.write(bytes,0,hasRead);
}
inputStream.close();
currentPart.close();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public double loadRate()
{
int sum = 0;
for (int i = 0; i < threadNum; i++) {
sum += threads[i].length;
System.out.println(threads[i].length);
}
return sum * 1.0 / fileSize;
}
public static void main(String[] args) throws IOException, InterruptedException {
DownUtil downUtil = new DownUtil("http://www.crazyit.org/data/attachment/album/201805/10/103528r04u4m2m01qec0oy.jpg" , "xxx.png" , 4);
downUtil.downLoad();
//Thread.sleep(1000);
Runnable runnable = ()->{
System.out.println(downUtil.loadRate());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
new Thread(runnable).start();
}
}