⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multithreadgetfile.java

📁 用java编制的断点续传的源程序
💻 JAVA
字号:
package com.downfile;

/**
 * 多线程下载调度程序
 */
import java.io.File;

import java.net.HttpURLConnection;
import java.net.URL;

import java.util.StringTokenizer;

/**
 * 多线程下载调度程序
 */
public class

MultiThreadGetFile extends Thread {
    long startPos = 0, endPos = 0;
    String currentFileThreadName; //要带上完整的路径
    String urlFile; //网络文件地址
    String urlFileName; //网络文件名
    String localFileAddress; //下载文件要存放的地址
    String localFileAddress0; //用于保留原始地址
    int threadNum; //要同时下载的线程数
    long[] eachThreadLength; //每个线程要下功的文件分块的大小
    long urlFileLength; //网络文件的大小
    URL url;
    HttpURLConnection httpURLConnection;
    String tempDirctoryHead = "tmp"; //用于存放下载文件的临时文件夹的前面部份,这里为"tmp"
    String tempStoreDirectory;
    FileDownInformationWithXML xmlFile;
    //public static boolean[] checkList; //检测线程
    //是否有必要建立下载文件存存放目录,如果是已经下了部份文件,就不用,采用断点续传的方式
    boolean needCreateNewDirectory = true;
    
    public MultiThreadGetFile() {
        
    }
    public MultiThreadGetFile(String urlFile, int threadNum, 
                              String localFileAddress) {
        this.urlFile = urlFile;
        this.threadNum = threadNum; //要同时下载的线程数
        if (createDirectory(localFileAddress) == false) {
            System.out.println("创建文件夹失败,请确认您是否有权限!");
            return;
        }
        this.localFileAddress = localFileAddress;
        this.localFileAddress0 = localFileAddress;
        xmlFile = new FileDownInformationWithXML(localFileAddress);
        //确定在XML文件中是否存在下载记录,没有返回null值
        String localFileAddressNow = xmlFile.downFileExist(urlFile);
        if (localFileAddressNow != null) { //如果存在
            this.localFileAddress = localFileAddressNow;
            needCreateNewDirectory = false;
        } else {
            //不存在就增加一个下载项到XML文件中去
            //这里一定要同步,否则其它的线程访问的时候由于这个线程已经对这个程序的更改
            //那么访问所得到的结果是不一样的
            //在文件合并中,也是一样需要实现线程同步的
            synchronized (this) {
                xmlFile.addOneDownRecord(urlFile, 
                                         getTempStoreDirectory(localFileAddress));
                xmlFile.saveChange();
            }

        }
    }

    private String getTempStoreDirectory(String localFileAddress) {
        //否则就建立新的目录
        String tempDirctory = localFileAddress + tempDirctoryHead;
        //如果是断点续传,那么断点续传的目录就是从XML文件中取得的目录,其它的就不管了
        if (needCreateNewDirectory == false)
            return localFileAddress;
        String tNum = "";

        while (true) {
            tempDirctory = tempDirctory + tNum;
            File file = new File(tempDirctory);
            if (!file.exists()) {
                break;
            }
            tNum = "0";
        }
        return tempDirctory;
    }

    /**
     * @localFileAddress 存放文件的路径
     * 该函数主要是在本地路径不存在的情况下,创建本地存放路径,是真假返回创建结果
     */
    private boolean createDirectory(String localFileAddress) {
        File file = new File(localFileAddress);
        if (!file.exists()) {
            try {
                file.mkdir();
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }

    /**
     * 确定每个线程文件最终要写的文件在大小
     */
    private void init_getEachThreadLength() {
        long l;
        l = urlFileLength / threadNum;
        for (int i = 0; i < threadNum; i++) {
            if (i == threadNum - 1) //如果是分配最后一个线程了
            {
                eachThreadLength[i] = urlFileLength - i * l;
            } else
                eachThreadLength[i] = l;
        }
    }

    /**
     * 取得要下载的文件名
     * @param file 网络文件名及路径
     * @return 文件名及扩展名
     */
    private String GetFileName(String file) {
        StringTokenizer st = new StringTokenizer(file, "/");
        while (st.hasMoreTokens()) {
            file = st.nextToken();
        }
        return file;
    }

    private void init() {
        tempStoreDirectory = getTempStoreDirectory(localFileAddress);
        if (needCreateNewDirectory == true) {
            if (createDirectory(tempStoreDirectory) == false) //创建一个临时文件夹
            {
                System.out.println("创建文件夹失败,请确认您是否有权限!");
                return;
            }
        }
        eachThreadLength = new long[threadNum];
        try {
            url = new URL(urlFile);
            httpURLConnection = (HttpURLConnection)url.openConnection();
            urlFileLength = 
                    Long.parseLong(httpURLConnection.getHeaderField("Content-Length"));
            urlFileName = url.getFile(); //取得在服务器上的路径及文件名
            urlFileName = GetFileName(urlFileName); //取得文件名
            init_getEachThreadLength();
            httpURLConnection.disconnect();
            //checkList = new boolean[threadNum + 1];
            for (int i = 1; i <= threadNum; i++) {
                if (i > 1)
                    startPos = startPos + eachThreadLength[i - 2];
                endPos = startPos + eachThreadLength[i - 1];
                currentFileThreadName = 
                        tempStoreDirectory + "\\" + urlFileName + ".part" + i;
                //System.out.println("startPos:"+(startPos));
                //System.out.println("endPos:"+(endPos));
                //System.out.println("Size:"+(endPos-startPos));
                Thread thread = 
                    new Thread(new GetFileThread(urlFile, startPos, endPos, 
                                                 currentFileThreadName, i));
                thread.start();
                //checkList[i] = false; //表示该线程开始
            }
            //System.out.println("localFileAddress:"+localFileAddress0);
            //System.out.println("tempStoreDirectory:"+tempStoreDirectory);
            Thread policeThread = 
                new Thread(new PoliceThread(threadNum, localFileAddress0, 
                                            tempStoreDirectory,urlFile));
            policeThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        init();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -