上次說了,下載速度太慢,緣由是文件太多,並且每下載一個文件都須要鏈接一次FTP。形成了時間的大量浪費。java
因此,多線程啦。。。。。web
話很少說上代碼。。apache
線程類。。多線程
import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import common.DownloadStatus; import domain.FtpFile; import util.ConfigInfo; import util.FtpHelper; public class FTPDownLoadThread extends Thread { private static Logger logger = Logger.getLogger(FTPDownLoadThread.class); private List<FtpFile> list; private String local_downLoad_dir; public FTPDownLoadThread(List<FtpFile> list, String localDownLoadDir,String threadName) { super(); this.list = list; local_downLoad_dir = localDownLoadDir; super.setName(threadName); } @Override public void run() { String name = Thread.currentThread().getName(); if(list==null ||local_downLoad_dir==null){ logger.error("線程"+name+"參數錯誤"); return ; } int num = list.size(); int count = 0; int flag = 0 ; for (FtpFile file : list) { count++; logger.info("線程"+name+"開始下載"+num+"個文件中的第"+count+"個文件"); //FTP鏈接 FtpHelper ftpHelper = new FtpHelper(); ftpHelper.connect(ConfigInfo.getFtpHostName(), ConfigInfo.getPort(), ConfigInfo.getUsername(), ConfigInfo .getPassword()); //該文件工做空間集合 List<String> filepath = file.getList(); //文件下載到本地的路徑 String local_path = local_downLoad_dir; // 變動工做目錄 // 組合下載路徑 for (int i = 0; i < filepath.size(); i++) { //若是是空間默認的開始工做空間 if ("/".equals(filepath.get(i))) { local_path += filepath.get(i); } else { //其餘的工做空間 //變動工做空間 ftpHelper.changeDir(filepath.get(i)); //組合本地路徑 local_path += filepath.get(i) + "/"; } } logger.info("組合以後下載目錄爲:" + local_path); //若是本地工做路徑不存在,創建目錄 File local_file = new File(local_path); // synchronized (local_file) { if (!local_file.exists()) { local_file.mkdirs(); } // } //進行下載並返回下載結果 Boolean status = ftpHelper.downloadonefile(file .getFileName(), local_path + file.getFileName()); if (!(status)) flag++; //斷開FTP鏈接 ftpHelper.disconnect(); } if (flag != 0) { logger.error("線程"+name+"下載失敗"); } logger.info("線程"+name+"下載成功......."); } public List<FtpFile> getList() { return list; } public void setList(List<FtpFile> list) { this.list = list; } public String getLocal_downLoad_dir() { return local_downLoad_dir; } public void setLocal_downLoad_dir(String localDownLoadDir) { local_downLoad_dir = localDownLoadDir; } }
其實就是把以前的下載弄成一個線程類。。。dom
而後客戶端方法代碼:socket
public boolean executeDownload(List<FtpFile> list) { logger.info("進入FtpDownloadServiceImpl的executeDownload方法"); // 創建FTP鏈接工具類 int num = list.size(); logger.info("遍歷ftp目錄裏面文件的個數爲" + num); System.out.println("-----------------------------"+list.get(0).getList()); String local_downLoad_dir = ConfigInfo.getFtpDownLoadDir(); logger.info("獲得配置文件中下載目錄爲:" + local_downLoad_dir); int num_thread = ConfigInfo.getThreadNUM(); int per = num/num_thread; List<FTPDownLoadThread> threads = new ArrayList<FTPDownLoadThread>(); for(int i=1 ;i<=num_thread;i++){ if(i==num_thread){ //System.out.println(list.subList(i*per, num)); FTPDownLoadThread thread = new FTPDownLoadThread(new ArrayList<FtpFile>(list.subList((i-1)*per, num)), local_downLoad_dir, i+""); thread.start(); threads.add(thread); } else { //System.out.println(list.subList(i*per, num)); FTPDownLoadThread thread = new FTPDownLoadThread(new ArrayList<FtpFile>(list.subList((i-1)*per, per*i)), local_downLoad_dir, i+""); thread.start(); threads.add(thread); } } for(FTPDownLoadThread thread : threads){ try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } //判斷返回結果 logger.info("進入FtpDownloadServiceImpl的executeDownload方法結束"); return true; }
這裏沒啥東西,就是根據線程數量,平均分配下載文件,而後啓動下載。。
這裏須要注意的就是關於主線程和子線程。。因爲這個webservice須要返回結果,就是是否完成,因此,主線程必須等待子線程完成。因此這裏須要試用join方法。保證必須子線程所有完成。ide
可是有遇到問題了,報錯說 socket沒法鏈接。。。這是下次要說的了。。工具