java对ftp/sftp的操作
  rpftQGKxmDfJ 2023年11月02日 31 0

前言

首先了解ftp/sftp,这两个都是文件传输的协议,用于大文件的传输;ftp/sftp是客户端和服务端组成,两个端互相建立连接之后,可以上传下载文件。ftp与sftp主要的区别就是安全性上,sftp传输过程中会对内容进行加密,会更加安全,相对的效率会稍差些。

公司有个需求,编写一个任务,从机器A拉取文件或目录到机器B。如果配置了文件参数,那么拉取对应的文件,如果没有配置,将所有的文件拉取到B机器。

思路

大概的想了下,感觉比较简单,存在参数,下载对应文件到另一台机器;不存在参数,下载所有。仔细考虑了一下,发现还是有些东西的;

问题

  1. 首先存在参数,那么是否存在这个文件,不存在怎么处理?
  2. 转存文件时,是先下载文件到本地,再上传;还是说有其他方法?
  3. 转存所有文件,如何获得某个目录下所有文件?获得到文件后,是不是需要按照原来目录的形式上传?
  4. 机器B已经存在了文件,怎么进行处理?

解答

  1. 不存在文件,提示错误信息,并打印好日志
  2. 为了效率,直接从机器A得到文件流,然后和机器B建立连接,上传文件流
  3. 搜索了一下相关文件,没有发现可用的API;所以需要递归得到文件及文件所属目录;上传是按照源目录结构上传
  4. 已经存在的需要比对时间,进行处理

到这里,基本思路已经通畅;就可以进行编码了。

上干货

ftp使用的jar是 it.sauronsoftware.ftp4j sftp使用的jar是 com.jcraft.jsch

获得某个目录所有文件

下载所有文件思路是:从机器A的某个目录往下cd,遇到文件停止,遇到目录就继续往下。从而获得所有的文件绝对地址,组装为一个列表;然后遍历这个列表获得文件,逐个上传。

获得所有路径方法
/**
     * 获得目录下,所有的文件路径
     * @return
     */
    public static List<String> getAllFile(String host, int port, String username, String password, String proxyHost, Integer proxyPort, String path, Boolean hasProxy) {
        log.info(LogFormat.formatMsg("FtpUtil.getAllFile.start", "", "host=" + host + ",port=" + port + ",username=" + username +
                ",password=" + password + ",proxyHost=" + proxyHost + ",proxyPort=" + proxyPort + ",path=" + path));
        FTPClient client = null;
        List<String> fileList = new ArrayList<>();
        try {
            client = getFtpConnection(host, port, username, password, proxyHost, proxyPort, hasProxy);
            fileList = addList(fileList, client, path);
        } catch (Exception e) {
            log.info(LogFormat.formatMsg("FtpUtil.getAllFile.error", "", "e=" + e.getMessage()));
        } finally {
            client = null;
        }
        return fileList;
    }
递归获得目录 下所有文件路径
/**
     * 递归获得目录 下所有文件路径
     * @return
     */
    public static List<String> addList(List<String> list, FTPClient client, String path) {
        log.info(LogFormat.formatMsg("FtpUtil.addList.start", "", "path=" + path));
        try {
            if (path != null) {
                client.changeDirectory(path);
            }
            path = client.currentDirectory();
            FTPFile[] fileList = client.list();
            if (fileList.length == 0) {
                log.info(LogFormat.formatMsg("FtpUtil.getAllFile", "", "length is 0,return"));
                return list;
            } else {
                for (FTPFile ftpFile : fileList) {
                    String fileOrDirName = ftpFile.getName();
                    String dir = path + "/" + fileOrDirName;

                    int type = ftpFile.getType();
                    if (type == FTPFile.TYPE_DIRECTORY) {
                        //当前是目录,进入下一层
                        log.info(LogFormat.formatMsg("FtpUtil.getAllFile", "", "ftpFile type is dir"));
                        addList(list, client, dir);
                    } else if (type == FTPFile.TYPE_FILE) {
                        //当前是文件,放入list
                        log.info(LogFormat.formatMsg("FtpUtil.getAllFile", "", "ftpFile type is file"));
                        list.add(dir);
                    } else {
                        log.info(LogFormat.formatMsg("FtpUtil.addList", "ftpType=" + type, "dir=" + dir));
                    }
                }
            }
        } catch (Exception e) {
            log.info(LogFormat.formatMsg("FtpUtil.addList", "", "e=" + e));
        }
        log.info(LogFormat.formatMsg("FtpUtil.addList.end", "", "list=" + JSON.toJSONString(list)));
        return list;
    }
建立ftp连接
private static FTPClient getFtpConnection(String host, int port,
                                              String username, String password, String proxyHost, Integer proxyPort, Boolean hasProxy) throws Exception {

        FTPClient client = new FTPClient();
        client.connect(host, port);
        client.login(username, password);
        client.setPassive(true);
        client.setType(FTPClient.TYPE_AUTO);
        if (hasProxy) {
            //设置代理 开始  使用的是squid正向代理
            FTPProxyConnector type = new FTPProxyConnector(proxyHost, proxyPort);
            client.setConnector(type);
        }
        //设置代理结束
        return client;
    }
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  rvP2pqm8fEoB   2023年12月24日   34   0   0 ListJavaListJava
rpftQGKxmDfJ
作者其他文章 更多