当前位置:首页 » JAVA技术教程

java 多线程下载

2008-03-14 10:46 本站整理 浏览(7)

java 多线程下载

这两天开发了一个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();
        
    }
}