Ftp Android批量下载


思路

1.服务端提供一个返回指定文件下的List<String> files

2.客户端拿到 files 文件列表,遍历单个单个文件请求服务端拉取数据

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
public static boolean (String middlePath, String fileName, String localPath) throws IOException {

        return downloadFromFtp(url, port, username, password,middlePath, fileName, localPath);
    }

    public static boolean (String url, int port, String
            username, String password, String path, String fileName, String localpath) throws IOException {
boolean flag = false;
FTPClient ftp = new FTPClient();
//设置超时时间以毫秒为单位使用时,从数据连接读。
ftp.setDefaultTimeout(timeOut * 1000);
ftp.setConnectTimeout(timeOut * 1000);
ftp.setDataTimeout(timeOut * 1000);
ftp.setControlEncoding("utf-8");//此处设置为u8就不用转换编码格式了
        int reply;
        try {
            if (port > -1) {
                ftp.connect(url, port);
            } else {
                ftp.connect(url);//ftp默认的端口是21
            }
            //很多人写的是用ftp.getReplyCode()给获取连接的返回值,但是这样会导致storeFileStream返回null
            ftp.login(username, password);
            ftp.enterLocalActiveMode();
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return flag;
            }
            //切换目录 此处可以判断,切换失败就说明ftp上面没有这个路径
            ftp.changeWorkingDirectory(path);
            //上传文件
            OutputStream out = null;
            InputStream in = null;
            //创建本地的文件时候要把编码格式转回来
            File localDir = new File(localpath +"/" + path);
            if(!localDir.exists()){
                localDir.mkdirs();
            }
            File localFile = new File(localpath + "/" + path + "/" + fileName);
            out = new FileOutputStream(localFile);
            //ftp.enterLocalPassiveMode();
            in = ftp.retrieveFileStream(fileName);
            byte[] byteArray = new byte[4096];
            int read = 0;
            while ((read = in.read(byteArray)) != -1) {
                out.write(byteArray, 0, read);
            }
            //这句很重要 要多次操作这个ftp的流的通道,要等他的每次命令完成
            ftp.completePendingCommand();
            out.flush();
            out.close();
            ftp.logout();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                ftp.disconnect();
            }
        }
        return flag;
    }

downloadFromFtp 传入参数说明 String

参数解释
urlftp 的 ip 地址
portftp 的端口 (默认 21)
usernameportftp 用户名
passwordftp 密码
path特别重要,一开报输入流为 null 就是因为它写错了;假如你的 ftp 根目录为 C:/ftp/,你想要下载 C:/ftp/xxx/下的文件,那么 path 就要写 xxx/
fileName下载文件的名称
localpath下载到本地的路径

server 返回制定文件列表

用户给定一个 path,查处 path 下所有的文件,放在 list,以 json 形式返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 递归查询所有的文件
public ArrayList listFiles(String path,ArrayList files){
    File directory = new File(path);
    File[] currentFiles = directory.listFiles();
    for (File file:currentFiles) {
        if (file.isDirectory()){
            listFiles(file.getPath(),files);
        }else{
            files.add(file);
        }
    }
    return files;
}

client 获取返回列表下载文件

四类线程池基本的线程池概述,这边按需求选择,我这里选了定长线程池 FixedThreadPool

  • FixedThreadPool 定长的线程池,初始化时指定线程的个数,当线程池中线程被用完时,其他任务阻塞等待
  • CachedThreadPool 不定长线程池,无限扩大的线程池,来几个任务分配几个线程。
  • SimpleThreadPool 单例线程,底层采用 LinkedBlockQueue 实现,除了排在队列最前面的线程以外的其他线程都要等着。
  • ScheduleThreadPol 在初始化时可以指定时间帮助我们处理延时任务和定时任务。

客户端的思路:
1.使用 HttpClient 从后台发送请求获取待下载 files 列表
2.将 DownloadThread 分配给 FixedThreadPool 运行

这边主要看 DownloadThread.java 如何编写,以及如何分配给 fixedThreadPool

DownloadThread.java

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
package com.bim.task;

import com.bim.common.FtpUtils;

import java.util.List;

public class DownLoadThread implements Runnable {

    List files = null;
    String ftpPath = null;
    String baseLocalPath = null;

    public  DownLoadThread(List files,String ftpPath,String baseLocalPath){
        this.files = files;
        this.ftpPath = ftpPath;
        this.baseLocalPath = baseLocalPath;
    }

    // 下载文件的具体业务
    // ftpPath ftp地址(c:/ftp)
    // baseLocalPath 目标地址
    private void downloadFile(String file,String ftpPath,String baseLocalPath) throws Exception{
        String dllPath = file.toString().replaceAll("\\\\","/");
        int lastIndexOf = dllPath.lastIndexOf("/");
        String middlePath = "/";
        if(ftpPath.length() - 1 <= lastIndexOf){
            middlePath = dllPath.substring(ftpPath.length(),lastIndexOf+1);
        }
        String fileName = dllPath.substring(lastIndexOf + 1,dllPath.length());
        System.out.println("filename" + fileName);
        System.out.println("baseLocalPath" + baseLocalPath);
        System.out.println("开始下载:" + middlePath + fileName + "到本地" + baseLocalPath);
        // 调用ftp下载文件
        FtpUtils.downloadFromFtp(middlePath,fileName,baseLocalPath);
        System.out.println(middlePath + fileName + "下载成功");

    }
    
    
    public void run() {
        try{
            while(!files.isEmpty()){
                String file = null;
                synchronized(files){
                    file = (String) files.get(0);
                    files.remove(0);
                }
                downloadFile(file,ftpPath,baseLocalPath);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

主程序拿到 files 后的逻辑代码部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class PullFileClient {
     private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
    
     public static void main(String[] args) throws IOException {

        Map<String,Object> resultMap = client.sendGet(requestUrl);
        Object code = resultMap.get("code");
        // 获取文件列表数据
        List files = (List) resultMap.get("data");
        // ftp的根目录 (c:/ftp)
        String ftpPath = "c:/FTP/";
        String baseLocalPath = "/home/zyh/Documents/tmp4/";
        fixedThreadPool.execute(new DownLoadThread(files,ftpPath,baseLocalPath));
        fixedThreadPool.shutdown();
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值