上次说了,下载速度太慢,缘由是文件太多,并且每下载一个文件都须要链接一次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没法链接。。。这是下次要说的了。。工具