这两天开发了一个Java的多线程下载程序,只支持Http下载,而且暂时没有提供断定续传功能。
共三个文件:Main.java,DownloadThread.java,MergeFile.java。
原代码如下:
package donwload;
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL;
public class DownloadThread extends Thread { private URL url; private int length; private int offset; private OutputStream bos; private String filePath; public void run() { Main.SINGAL++; System.out.println("线程" + this.getId() + "开始下载"); try { System.out.println("length:" + length); System.out.println("off:" + offset); HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection(); httpConnection.setRequestProperty("RANGE","bytes=" + offset + "-"); InputStream ins = httpConnection.getInputStream(); bos = new FileOutputStream(new File(filePath), false); byte[] buffer = new byte[1024]; int bytesRead; int size = 0; while ((bytesRead = ins.read(buffer)) != -1) { size += bytesRead; if (size > length) { bytesRead = bytesRead - (size - length); } bos.write(buffer, 0, bytesRead); System.out.println("线程" + this.getId() + "下载了" + bytesRead + "字节"); if (size > length) { break; } } bos.close(); } catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); } System.out.println("线程" + this.getId() + "已经完成"); Main.SINGAL--; }
public DownloadThread(URL url, int length, int offset, String filePath) { super(); this.url = url; this.length = length; this.offset = offset; this.filePath = filePath; }
public OutputStream getBos() { return bos; }
public void setBos(OutputStream bos) { this.bos = bos; } } |
package donwload;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;
public class MergeFile extends Thread {
private int threadNumber; private String fileName; private String downLoadPath; public MergeFile(int threadNumber, String downLoadPath, String fileName) { super(); this.threadNumber = threadNumber; this.downLoadPath = downLoadPath; this.fileName = fileName; }
public void run() { while (!(Main.SINGAL == 0 && Main.START_DOWNLOAD)) { try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace(); } } try { System.out.println("文件开始合并"); OutputStream bos = new FileOutputStream(new File(downLoadPath + fileName), false); for (int i = 0; i<threadNumber; i++) { File file = new File(downLoadPath + fileName + ".part" + i); InputStream is = new FileInputStream(file); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } is.close(); file.delete(); } bos.close(); System.out.println("文件合并完成"); } catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); } Main.START_DOWNLOAD = false; }
public int getThreadNumber() { return threadNumber; }
public void setThreadNumber(int threadNumber) { this.threadNumber = threadNumber; }
public String getFileName() { return fileName; }
public void setFileName(String fileName) { this.fileName = fileName; }
public String getDownLoadPath() { return downLoadPath; }
public void setDownLoadPath(String downLoadPath) { this.downLoadPath = downLoadPath; }
}
|
package donwload;
import java.io.File; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL;
public class Main { public static int SINGAL = 0; public static boolean START_DOWNLOAD = false; private int threadNumber; private String fileName; private String downLoadPath; private URL url; public Main(URL url) { super(); this.url = url; this.threadNumber = 5; this.downLoadPath = "c:/download/"; try { this.fileName = java.net.URLDecoder.decode(url.getFile().substring(url.getFile().lastIndexOf("/") + 1, url.getFile().length()), "GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace(); } }
public Main(int threadNumber, String fileName, String downLoadPath, URL url) { super(); this.threadNumber = threadNumber; this.fileName = fileName; this.downLoadPath = downLoadPath; this.url = url; }
public void download() throws Exception { System.out.println("文件开始下载"); START_DOWNLOAD = true; HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); int contentLength = httpURLConnection.getContentLength(); int partLength = contentLength / threadNumber + 1; for (int i=0; i<threadNumber; i++) { int length = partLength; if (i == threadNumber - 1) { length = contentLength - i * partLength; } DownloadThread dt = new DownloadThread(url, length, i * partLength, downLoadPath + fileName + ".part" + i); dt.start(); } }
public int getThreadNumber() { return threadNumber; }
public void setThreadNumber(int threadNumber) { this.threadNumber = threadNumber; }
public String getDownLoadPath() { return downLoadPath; }
public void setDownLoadPath(String downLoadPath) { this.downLoadPath = downLoadPath; }
public String getFileName() { return fileName; }
public void setFileName(String fileName) { this.fileName = fileName; }
public URL getUrl() { return url; }
public void setUrl(URL url) { this.url = url; }
public static void main(String[] args) throws Exception{ String urlAddress = "http://www.cssxblog.net/qin/mp3/aqzy.mp3";
URL url = new URL(urlAddress); int threadNumber = 5; String fileName = "test.mp3"; String downLoadPath = "c:/download/"; new File(downLoadPath).mkdir(); //下载
Main m = new Main(url); m.setThreadNumber(threadNumber); m.download(); //合并文件
fileName = m.getFileName(); Thread mergeFile = new MergeFile(threadNumber, downLoadPath, fileName); mergeFile.start(); } }
|