JAVA写的WEB迅雷

实现原理:

 用httpConnection.setRequestProperty("RANGE" , "bytes= xxx -xxx" );获取指定的数据块

用RandomAccessFile实现文件随机访问,写入指定数据块到文件.

关键事项:获取远程文件大小,根据文件大小确定下载线程个数(可固定线程数,也可固定每个线程下载数据块大小,用户自己决定).

 

package org.ifusing.down;

 

import java.io.*;

import java.net.*;

/**

  * 文件下载管理类

  */

public class DownLoadManager {

    /**

      * 每个线程下载的字节数

      */

    static final long unitSize = 100 * 1024;

 

    /**

      * 启动多个线程下载文件

      */

    public void doDownload(String remoteFileUrl)

            throws IOException {

       

        String fileName = new URL(remoteFileUrl).getFile();

        fileName = fileName.substring(fileName.lastIndexOf( "/" )+1,fileName.length()).replace( "%20" , " " );

           

        long fileSize = this .getRemoteFileSize(remoteFileUrl);

 

        if (fileSize == 0){

            return ;

        }

       

        this .createFile(fileName, fileSize);

 

        long threadCount = fileSize / unitSize ;

        System. out .println( " 共启动 "

                + (fileSize % unitSize == 0 ? threadCount : threadCount + 1)

                + " 个线程" );

 

        long offset = 0;

        if (fileSize <= unitSize ) { // 如果远程文件尺寸小于等于unitSize

            DownloadThread downloadThread = new DownloadThread(remoteFileUrl,

                    fileName, offset, fileSize);

            downloadThread.start();

        } else { // 如果远程文件尺寸大于unitSize

            for ( int i = 1; i <= threadCount; i++) {

                DownloadThread downloadThread = new DownloadThread(

                        remoteFileUrl, fileName, offset, unitSize );

                downloadThread.start();

 

                offset = offset + unitSize ;

            }

            if (fileSize % unitSize != 0) { // 如果不能整除,则需要再创建一个线程下载剩余字节

                DownloadThread downloadThread = new DownloadThread(

                        remoteFileUrl, fileName, offset, fileSize

                                - unitSize * threadCount);

                downloadThread.start();

 

            }

        }

 

    }

 

    /**

      * 获取远程文件尺寸

      */

    private long getRemoteFileSize(String remoteFileUrl) throws IOException {

 

        long fileSize = 0;

        HttpURLConnection httpConnection = (HttpURLConnection) new URL(

                remoteFileUrl).openConnection();

       

        httpConnection.setRequestMethod( "HEAD" );

       

        int responseCode = httpConnection.getResponseCode();

        if (responseCode >= 400){

            System. out .println( "Web 服务器响应错误!" );

            return 0;

        }

       

        String sHeader;

        for ( int i=1;;i++){

            sHeader = httpConnection.getHeaderFieldKey(i);

            if (sHeader != null && sHeader.equals( "Content-Length" )){

                System. out .println( " 文件大小ContentLength:" +httpConnection.getContentLength());

                fileSize = Long.parseLong (httpConnection.getHeaderField(sHeader));

                break ;

            }

        }

 

        return fileSize;

    }

 

    /**

      * 创建指定大小的文件

      */

    private void createFile(String fileName, long fileSize) throws IOException {

        File newFile = new File(fileName);

        RandomAccessFile raf = new RandomAccessFile (newFile, "rw" );

 

        raf.setLength(fileSize);

 

        raf.close();

    }

 

}

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package org.ifusing.down ;

 

import java.io.BufferedInputStream;

import java.io.File;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

 

/**

  * 负责文件下载的类

  */

public class DownloadThread extends Thread {

    /**

      * 待下载的文件

      */

    private String url = null ;

 

    /**

      * 本地文件名

      */

    private String fileName = null ;

 

    /**

      * 偏移量

      */

    private long offset = 0;

 

    /**

      * 分配给本线程的下载字节数

      */

    private long length = 0;

 

    /**

      * @param url 下载文件地址

      * @param fileName 另存文件名

      * @param offset 本线程下载偏移量

      * @param length 本线程下载长度

      *

      * @author Angus.wang

      * */

    public DownloadThread(String url, String file, long offset, long length) {

        this . url = url;

        this . fileName = file;

        this . offset = offset;

        this . length = length;

        System. out .println( " 偏移量=" + offset + "; 字节数=" + length);

    }

 

    public void run() {

        try {

            HttpURLConnection httpConnection = (HttpURLConnection) new URL(

                    this . url ).openConnection();

 

            httpConnection.setRequestMethod( "GET" );

            httpConnection.setRequestProperty( "RANGE" , "bytes=" + this . offset

                    + "-" + ( this . offset + this . length - 1));

           

            System. out .println( "RANGE bytes=" + this . offset + "-" + ( this . offset + this . length - 1) http://www.kcvg.cn 原创);

 

           

            BufferedInputStream bis = new BufferedInputStream(httpConnection

                    .getInputStream());

 

            byte [] buff = new byte [1024];

            int bytesRead;

            File newFile = new File( fileName );

            RandomAccessFile raf = new RandomAccessFile(newFile, "rw" );

           

           

            while ((bytesRead = bis.read(buff, 0, buff. length )) != -1) {

                raf.seek( this . offset );

                raf.write(buff, 0, bytesRead);

               

                this . offset = this . offset + bytesRead;

            }

           

            raf.close();

            bis.close();

        } catch (IOException ioe) {

            ioe.printStackTrace();

        }

 

    }

 

}

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package org.ifusing.downtest ;

 

/**

  * 多线程文件下载测试

  * */

public class FileDownloadTest {

 

    /**

      * @param args

      */

    public static void main(String[] args) {

        try {

            String remoteFileUrl = "http://dl_dir.qq.com/qqfile/qq/QQ2009/QQ2009SP5.exe" ;

           

            DownLoadManager downLoadManager = new DownLoadManager();

           

            downLoadManager.doDownload(remoteFileUrl);

        } catch (Exception e){

            e.printStackTrace();

        }

       

 

    }

 

}

你可能感兴趣的:(java,多线程,Web,.net,qq)