用commons-net包写Ftp客户端下载(四)

上次说了,下载速度太慢,原因是文件太多,而且每下载一个文件都需要连接一次FTP。造成了时间的大量浪费。

所以,多线程啦。。。。。

话不多说上代码。。

线程类。。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
importjava.io.File;
importjava.util.ArrayList;
importjava.util.List;
 
importorg.apache.log4j.Logger;
 
importcommon.DownloadStatus;
importdomain.FtpFile;
importutil.ConfigInfo;
importutil.FtpHelper;
 
 
 
publicclassFTPDownLoadThreadextendsThread {
    privatestaticLogger logger = Logger.getLogger(FTPDownLoadThread.class);
     
    privateList<FtpFile> list;
    privateString local_downLoad_dir;
     
     
     
    publicFTPDownLoadThread(List<FtpFile> list, String localDownLoadDir,String threadName) {
        super();
        this.list = list;
        local_downLoad_dir = localDownLoadDir;
        super.setName(threadName);
    }
     
    @Override
    publicvoidrun() {
        String name = Thread.currentThread().getName();
        if(list==null||local_downLoad_dir==null){
            logger.error("线程"+name+"参数错误");
            return;
        }
        intnum = list.size();
        intcount =0;
        intflag =0;
        for(FtpFile file : list) {
            count++;
            logger.info("线程"+name+"开始下载"+num+"个文件中的第"+count+"个文件");
            //FTP连接
            FtpHelper ftpHelper =newFtpHelper();
            ftpHelper.connect(ConfigInfo.getFtpHostName(),
                    ConfigInfo.getPort(), ConfigInfo.getUsername(), ConfigInfo
                            .getPassword());
             
            //该文件工作空间集合
            List<String> filepath = file.getList();
            //文件下载到本地的路径
            String local_path = local_downLoad_dir;
             
            // 变更工作目录
            // 组合下载路径
            for(inti =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 =newFile(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+"下载成功.......");
         
 
    }
 
    publicList<FtpFile> getList() {
        returnlist;
    }
    publicvoidsetList(List<FtpFile> list) {
        this.list = list;
    }
    publicString getLocal_downLoad_dir() {
        returnlocal_downLoad_dir;
    }
    publicvoidsetLocal_downLoad_dir(String localDownLoadDir) {
        local_downLoad_dir = localDownLoadDir;
    }
     
     
}

其实就是把之前的下载弄成一个线程类。。。

然后客户端方法代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
publicbooleanexecuteDownload(List<FtpFile> list) {
        logger.info("进入FtpDownloadServiceImpl的executeDownload方法");
        // 建立FTP连接工具类
 
        intnum = list.size();
        logger.info("遍历ftp目录里面文件的个数为"+ num);
 
        System.out.println("-----------------------------"+list.get(0).getList());
 
 
        String local_downLoad_dir = ConfigInfo.getFtpDownLoadDir();
        logger.info("得到配置文件中下载目录为:"+ local_downLoad_dir);
 
        intnum_thread = ConfigInfo.getThreadNUM();
        intper = num/num_thread;
        List<FTPDownLoadThread> threads =newArrayList<FTPDownLoadThread>();
        for(inti=1;i<=num_thread;i++){
            if(i==num_thread){
                //System.out.println(list.subList(i*per, num));
                FTPDownLoadThread thread  =newFTPDownLoadThread(newArrayList<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 =newFTPDownLoadThread(newArrayList<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方法结束");
        returntrue;
    }
这里没啥东西,就是根据线程数量,平均分配下载文件,然后启动下载。。

这里需要注意的就是关于主线程和子线程。。由于这个webservice需要返回结果,就是是否完成,所以,主线程必须等待子线程完成。所以这里需要试用join方法。保证必须子线程全部完成。

但是有遇到问题了,报错说 socket无法连接。。。这是下次要说的了。。

你可能感兴趣的:(用commons-net包写Ftp客户端下载(四))