因爲上次說了,若是客戶端遍歷FTP服務器的話,若是FTP上文件數量很大,那樣的話,遞歸遍歷的時間會超級長。。java
(尚未說明。。咱們這是EJB項目。。是FTP服務器上調用個人這個客戶端進行下載。。我只想這個EJB客戶端是發佈在另外一臺web
機器上的。。)apache
因此我就考慮,是否能夠服務器端本身遍歷,本身遍歷FTP的文件夾,而後把遍歷的結果經過webservice傳給我。由於,本地遍歷服務器
的所須要的時間不多不多。好比13000個文件若是客戶端遍歷FTP服務器大概須要3個小時以上,而後本地遍歷就1.4秒。。多線程
很無語的效率。。因此服務器斷遍歷以後生成我須要的數據,而後傳給我,我那道以後直接開始下載便可。。工具
FTP服務器端遍歷工具類。。。(其實就是文件遍歷。。)spa
import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.log4j.Logger; import ftpdownloadservice.FtpFile;//webservice /** * * 文件操做工具類 * * @author houly * */ public class FileUtil { // 日誌 private static Logger logger = Logger.getLogger(FileUtil.class); public static List<FtpFile> traversalDir(File dir, List<FtpFile> list) { // logger.info("開始進入FileUtil中的traversalDir方法......"); // 判斷參數 if (dir == null) { logger.error("參數爲空....."); return null; } // 判斷複製目錄是不是目錄 if (!dir.isDirectory()) { logger.error("開始目錄設置錯誤...."); return null; } // 列出該目錄下的全部文件 File[] files = dir.listFiles(); if (list == null) list = new ArrayList<FtpFile>(); for (int i = 0; i < files.length; i++) { File file = files[i]; // 遞歸調用...... if (file.isDirectory()) { traversalDir(file,list); } else { list.add(change(file,new File( ReadProperties.readProperties("rrs.properties", "ftpimagepath")))); } } // logger.info("開始進入FileUtil中的traversalDir方法結束......"); return list; } public static FtpFile change(File file,File dir){ if(file.isDirectory()){ logger.error("目標文件是目錄"); return null; } if(dir==null || dir.isFile()){ logger.error("目錄參數出錯....."); return null; } String path = dir.getAbsolutePath(); String filePath = file.getAbsolutePath(); int index_begin = filePath.indexOf(path); if(index_begin == -1 ){ return null; } index_begin = path.length()-1; FtpFile ftpFile = new FtpFile(); ftpFile.setFileName(file.getName()); while(true){ int index_end = filePath.indexOf("\\", index_begin+1); if(index_end == index_begin+1 ){ ftpFile.getList().add("/"); } else if(index_end == -1){ break; } else{ ftpFile.getList().add(filePath.substring(index_begin+1, index_end)); } index_begin = index_end; } // logger.info("內容"); // logger.info(ftpFile.getList()); return ftpFile; }
很簡單很少說了。。。線程
再發下客戶端代碼把。。。更改以後的。。。日誌
public boolean executeDownload(List<FtpFile> list) { logger.info("進入FtpDownloadServiceImpl的executeDownload方法"); int num = list.size(); logger.info("遍歷ftp目錄裏面文件的個數爲" + num); String local_downLoad_dir = ConfigInfo.getFtpDownLoadDir(); logger.info("獲得配置文件中下載目錄爲:" + local_downLoad_dir); int flag = 0; //根據遍歷結果從FTP上下載文件 int count = 0; for (FtpFile file : list) { count++; logger.info("開始下載"+num+"個文件中的第"+count+"個文件"); //FTP鏈接 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); if (!local_file.exists()) { local_file.mkdirs(); } //進行下載並返回下載結果 Boolean status = ftpHelper.downloadonefile(file .getFileName(), local_path + file.getFileName()); if (!status) flag++; //斷開FTP鏈接 ftpHelper.disconnect(); } //判斷返回結果 logger.info("進入FtpDownloadServiceImpl的executeDownload方法結束"); if (flag != 0) { return false; } return true; }
原本認爲這樣就會沒事的。。可是發現單線程下載FTP速度太慢。。局域網裏面,不限速的清空,13000多文件,400多Mcode
須要時間1個半小時。。。仍是時間太長。。因而,多線程。。。。(命苦啊。。。。)