java中多线程下载

package com.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MutileThreadDown {
private static int blockCount=3;
private static int blockSize;
	public static void main(String[] args) throws Exception{
		String path="http://localhost:8080/Web025Server/media/bootstrap.avi";
		
		URL url=new URL(path);
		
		HttpURLConnection conn=(HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(10000);
		conn.setReadTimeout(5000);
		int responseCode=conn.getResponseCode();
		if(responseCode==200){
			int size=conn.getContentLength();
			System.out.println("服务器端的长度"+size);
			blockSize=size/blockCount;
			
			//创建一个跟服务器端大小相同的空白文件
			File file=new File("aa.avi");
			RandomAccessFile raf=new RandomAccessFile(file,"rw");
			raf.setLength(size);//设置文件的的大小
			//2.开启若干个子线程,分别下载资源
			for(int i=1;i<=blockCount;i++){
				int startIndex=(i-1)*blockSize+0;
				int endIndex=i*blockSize-1;
				if(i==blockCount){
					endIndex=size-1;
				}
				new DownLoadThread(startIndex, endIndex, i, path).start();;
				System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex);
			}
		}
		conn.disconnect();
	}
	
	//定义一个线程的内部类
	private static class DownLoadThread extends Thread{
		private int startIndex;
		private int endIndex;
		private int threadi;
		private String path;
		public DownLoadThread(int startIndex, int endIndex, int threadi,
				String path) {
			super();
			this.startIndex = startIndex;
			this.endIndex = endIndex;
			this.threadi = threadi;
			this.path = path;
		}
		@Override
		public void run() {

			try {
				String path="http://localhost:8080/Web025Server/media/bootstrap.avi";
				
				URL url=new URL(path);
				
				HttpURLConnection conn=(HttpURLConnection) url.openConnection();
				conn.setRequestMethod("GET");
				conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
				conn.setConnectTimeout(10000);
				conn.setReadTimeout(5000);
				int responseCode=conn.getResponseCode();
				System.out.println("服务器的响应码"+responseCode);
				
				//创建一个跟服务器端大小相同的空白文件
				File file=new File("aa.avi");
				RandomAccessFile raf=new RandomAccessFile(file,"rw");
				InputStream in=conn.getInputStream();
				raf.seek(startIndex);//从哪个位置开始写文件
				int len=-1;
				byte[] bytes=new byte[1024];
				while((len=in.read(bytes))!=-1){
					raf.write(bytes, 0, len);
				}
				in.close();
				raf.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
	}
	
	

}

下面我再贴一下更新后的代码吧,这个可以实现短点下载,关闭程序重新开启后可以继续下载

package com.download;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MutileThreadDown {
private static int blockCount=3;//定义需要开启线程的个数
private static int blockSize;

private static int runningThreadCount;//正在运行的线程的数量
	public static void main(String[] args) throws Exception{
		
		String path="http://localhost:8080/Web025Server/media/bootstrap.avi";
		URL url=new URL(path);
		HttpURLConnection conn=(HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(10000);
		conn.setReadTimeout(5000);
		
		int responseCode=conn.getResponseCode();
		if(responseCode==200){
			int size=conn.getContentLength();
			System.out.println("服务器端的长度"+size);//服务器端需要下载文件的大小
			blockSize=size/blockCount;
			
			//创建一个跟服务器端大小相同的空白文件
			File file=new File("aa.avi");
			RandomAccessFile raf=new RandomAccessFile(file,"rw");
			raf.setLength(size);//设置文件的的大小
			//2.开启若干个子线程,分别下载资源
			runningThreadCount=blockCount;//刚开始设定正在运行的线程数是线程的总数
			for(int i=1;i<=blockCount;i++){
				int startIndex=(i-1)*blockSize+0;
				int endIndex=i*blockSize-1;
				if(i==blockCount){
					endIndex=size-1;//最后一个线程需要下载剩下的
				}
				new DownLoadThread(startIndex, endIndex, i, path).start();;
				System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex);
			}
		}
		conn.disconnect();
	}
	
	//定义一个线程的内部类
	private static class DownLoadThread extends Thread{
		private int startIndex;
		private int endIndex;
		private int threadi;
		private String path;
		public DownLoadThread(int startIndex, int endIndex, int threadi,
				String path) {
			super();
			this.startIndex = startIndex;
			this.endIndex = endIndex;
			this.threadi = threadi;
			this.path = path;
		}
		@Override
		public void run() {

			try {
				//获取当前下载总文件的大小
				int total=0;
				File filepos=new File(threadi+".txt");//建立一个txt文件记录下载的信息
				String path="http://localhost:8080/Web025Server/media/bootstrap.avi";
				
				URL url=new URL(path);
				
				HttpURLConnection conn=(HttpURLConnection) url.openConnection();
				conn.setRequestMethod("GET");
				//接着从上一次位置下载
				if(filepos.exists()&&filepos.length()>0){//判断以前是否下载过
				FileInputStream fis=new FileInputStream(filepos);
				BufferedReader br=new BufferedReader(new InputStreamReader(fis));
				String lasttotalstr=br.readLine();//获取当前线程上一次下载的总大小
				int lasttotal=Integer.valueOf(lasttotalstr);
				System.out.println("上一次下载的总大小"+lasttotal);
				startIndex+=lasttotal;
				total+=lasttotal;
				fis.close();//很重要
				}
				
				conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
				conn.setConnectTimeout(10000);
				conn.setReadTimeout(5000);
				int responseCode=conn.getResponseCode();
				System.out.println("服务器的响应码"+responseCode);
				
				//创建一个跟服务器端大小相同的空白文件
				File file=new File("aa.avi");
				RandomAccessFile raf=new RandomAccessFile(file,"rw");
				InputStream in=conn.getInputStream();
				raf.seek(startIndex);//从哪个位置开始写文件
				int len=-1;
				byte[] bytes=new byte[1024*1024];

				
				while((len=in.read(bytes))!=-1){
					RandomAccessFile rf=new RandomAccessFile(filepos, "rwd");
					raf.write(bytes, 0, len);
					total+=len;
					rf.write(String.valueOf(total).getBytes());
					rf.close();
				}
				in.close();
				raf.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			} finally{
				synchronized (this) {
					runningThreadCount--;
					if(runningThreadCount==0){
						System.out.println("所有线程下载完毕,可以删除txt记录文件了");//可能会出现线程安全问题
						for(int i=1;i<=blockCount;i++){
							File f=new File(i+".txt");
							boolean b=f.delete();
							System.out.println(b);
						}
					}
				}
				
			}
		}
	}
	
	

}


你可能感兴趣的:(java,多线程,下载)