java 多线程下载功能

时间:2023-03-08 16:37:53
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; public class Demo { private static int threadCount = 3;
/**
* 多线程下载测试类
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception { //1、连接服务器,获取一个文件,获取文件的长度,在本地创建一个大小跟服务器文件一样大的临时文件
String path = "http://192.168.1.100:8080/test.avi";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code==200)
{ //服务器返回的数据长度 实际上就是文件的长度
int length = conn.getContentLength();
System.out.println("文件总长度:"+length); //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//指定创建的这个文件的长度
raf.setLength(length);
raf.close(); //假设是3个线程去下载资源
//平均每一个线程下载的文件的大小
int blockSize = length / threadCount;
for(int threadId=1;threadId<=threadCount;threadId++)
{
//线程下载的开始位置
int startIndex = (threadId-1)*blockSize;
int endIndex = threadId*blockSize;
if(threadId==threadCount)
{
endIndex = length; }
System.out.println("线程:"+threadId+" 下载:---"+startIndex+"--->"+endIndex); //启动线程
new DownloadThread(threadId,startIndex,endIndex,path).start();
} }
else
{
System.out.println("服务器错误");
} } public static class DownloadThread extends Thread
{
private int threadId; //线程id
private int startIndex;
private int endIndex;
private String path; public DownloadThread(int threadId, int startIndex, int endIndex,
String path) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
} public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET"); //重要 : 请求服务器下载部分的文件指定文件的位置
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); //从服务器请求全部资源 200 ok 如果从服务器请求部分资源 206 ok
int code = conn.getResponseCode();
System.out.println("code:"+code); //已经设置了请求的位置 返回的事当前位置对应的文件的输入流
InputStream is = conn.getInputStream(); //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//随机写文件的时候从哪个位置开始
raf.seek(startIndex); //定位文件 int len = 0;
byte[] buffer = new byte[1024];
while((len=is.read(buffer))!=-1)
{
raf.write(buffer,0,len);
} is.close();
raf.close(); System.out.println("线程:"+threadId+"下载完毕了。。。"); } catch (Exception e) {
e.printStackTrace();
}
} } }