FTPClient 文件 同步代码工具类

 分 本地同步到 FTP   和 FTP同步到本地 两种

 只依赖FTPClient 即可,其他部分替代即可。 

具体使用看main方法


import cn.hutool.core.io.FileUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 描述:
 *  FTP 同步工具
 * @Auther: huanggp
 * @Date: 2020/7/9
 * @Copyright: 2020 www.***.com Inc. All rights reserved.
 * @version: 1.0.0
 */
public class FTPFileSyncTool {

    private static Logger logger = LoggerFactory.getLogger(FTPFileSyncTool.class);
    private FTPClient ftpClient;

    private boolean isDelSourceFile = false;

    public FTPFileSyncTool(boolean isDelSourceFile) {
        this.isDelSourceFile = isDelSourceFile;
        ftpClient = new FTPClient();
    }


    /**
     * 同步本地文件到FTP
     * @param ftp   FTP配置信息
     * @param isDelSourceFile   是否删除源文件
     */
    public static int syncToFTP(FTP ftp ,boolean isDelSourceFile){
        int suc = 0;
        FTPFileSyncTool fd = new FTPFileSyncTool(isDelSourceFile);
        fd.connect(ftp);
        try {
            suc = fd.uploadDir(new File(ftp.getLocalFolder()), ftp.getFtpFolder());
        } catch (Exception e) {
            logger.error("同步失败,失败原因是:{}",e.getMessage());
        }
        // 释放
        fd.disconnect();
        return suc;
    }

    /**
     * 同步FTP文件到本地
     *
     * @param ftp {
     *            ftpFolder: 一定要以/  分隔符结尾
     *            localFolder: 一定要以/  分隔符结尾
     *            }
     */
    public static void syncToLocal(FTP ftp , boolean isDelSourceFile) {
        FTPFileSyncTool fd = new FTPFileSyncTool(isDelSourceFile);
        //链接
        fd.connect(ftp);
        // 同步
        fd.downDir(ftp.getFtpFolder(), ftp.getLocalFolder());
        // 释放
        fd.disconnect();
    }

    private int uploadDir(File file , String ftpPathPrefix) throws Exception{
        int suc = 0;
        if(file.isDirectory()){
            ftpClient.makeDirectory(ftpPathPrefix + file.getName());
            ftpClient.changeWorkingDirectory(ftpPathPrefix + file.getName());
            String[] files = file.list();
            if((files == null || files.length == 0) && isDelSourceFile) {
                FileUtils.deleteDirectory(file);
            }
            for (int i = 0; i < files.length; i++) {
                File file1 = new File(file.getPath()+"\\"+files[i] );
                if(file1.isDirectory()){
                    suc += uploadDir(file1,"");
                    ftpClient.changeToParentDirectory();
                }else{
                    uploadFile(new File(file.getPath() + "\\" + files[i]));
                    suc ++;
                }
            }
        }else{
            uploadFile(file);
            suc ++;
        }
        return suc;
    }

    private void uploadFile(File file) throws IOException {
        FileInputStream input = new FileInputStream(file);
        logger.info("准备上传文件:{}" , file.getPath());
        ftpClient.storeFile(file.getName(), input);
        input.close();
        logger.info("上传文件完毕,准备删除文件:{} , 是否删除:{}" , file.getPath() ,isDelSourceFile);
        if(isDelSourceFile){
            FileUtil.del(file);
        }
    }


    /**
     * 功能说明:通过递归实现ftp目录文件与本地文件同步更新
     */
    private void downDir(String ftpfilepath, String localpath) {
        try {
            FTPFile[] ftpFiles = ftpClient.listFiles(ftpfilepath);
            // 得到当前ftp目录下的文件列表
            if (ftpFiles != null) {
                for (FTPFile ftpFile : ftpFiles) {
                    String localfilepath = localpath + ftpFile.getName();
                    File localFile = new File(localfilepath);
                    // 根据ftp文件生成相应本地文件
                    Date fflastModifiedDate = ftpFile.getTimestamp().getTime();
                    // 获取ftp文件最后修改时间
                    Date localLastModifiedDate = new Date(localFile
                            .lastModified());
                    // 获取本地文件的最后修改时间
                    int lastUpdateTimeByLocalFile = localLastModifiedDate
                            .compareTo(fflastModifiedDate);
                    // lastUpdateTimeByLocalFile=0,两文件最后修改时间相同;lastUpdateTimeByLocalFile<0,本地文件的最后修改时间早于ftp文件最后修改时间;lastUpdateTimeByLocalFile>0,则相反
                    if (ftpFile.isDirectory()) {
                        // 如果是目录
                        localFile.mkdir();
                        // 如果本地文件夹不存在就创建
                        String ftpfp = ftpfilepath + ftpFile.getName() + "/";
                        // 转到ftp文件夹目录下
                        String localfp = localfilepath + File.separator;
                        // 转到本地文件夹目录下
                        this.downDir(ftpfp, localfp);
                        // 递归调用
                    } else if (ftpFile.isFile()) {
                        // 如果是文件
                        File lFile = new File(localpath);
                        lFile.mkdirs();
                        // 如果文件所在的文件夹不存在就创建
                        if (!lFile.exists()) {
                            return;
                        }
                        if (ftpFile.getSize() != localFile.length() || lastUpdateTimeByLocalFile < 0) {
                            // 如果ftp文件和本地文件大小不一样或者本地文件不存在或者ftp文件有更新,就进行创建、覆盖
                            String filepath = ftpfilepath + ftpFile.getName();
                            // 目标ftp文件下载路径
                            FileOutputStream fos = new FileOutputStream(
                                    localFile);
                            boolean downFileResult;
                            try {
                                downFileResult = ftpClient.retrieveFile(new String(
                                        filepath.getBytes("UTF-8"),
                                        "ISO-8859-1"), fos);
                                // 从FTP服务器上取回一个文件
                            } catch (Exception e) {
                                downFileResult = false;
                                logger.error("下载文件异常:{}", e);
                            }
                            String name = ftpFile.getName();
                            String dir = localpath;
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            String time = sdf.format(localFile.lastModified());
                            if (downFileResult && isDelSourceFile) {
                                ftpClient.deleteFile(filepath);
                                logger.debug("download file succussful:  fileName: {} ,   localpath: {}    time:{}  ", name, dir, time);
                            } else {
                                logger.info("download file failed:  fileName: {} ,   localpath: {}    time:{}  ", name, dir, time);
                            }
                            fos.flush();
                            fos.close();
                        } else {
                            //	System.out.println("两个文件相同!");
                        }
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    /**
     * 连接ftp服务器
     * @param ftp
     */
    private void connect(FTP ftp) {
        String hostip = ftp.getHost();
        int port = ftp.getPort();
        String username = ftp.getUsername();
        String password = ftp.getPassword();
        try {
            ftpClient.connect(hostip, port);
            // 连接服务器
            ftpClient.login(username, password);
            // 登录
            // 检测是否连接成功
            int reply = ftpClient.getReplyCode();
            // 看返回的值是不是230,如果是,表示登陆成功
            if (!FTPReply.isPositiveCompletion(reply)) {
                // 返回的code>=200&&code<300return
                ftpClient.disconnect();
                // 关闭FTP连接
            }
            ftpClient.setControlEncoding("UTF-8");
            // 设置字符编码
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            /**
             * 一定要使用被动模式,否则 listFiles
             *  linux 会卡住
             *  windows 暂未发现
             */
            ftpClient.enterLocalPassiveMode();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    /**
     * 释放链接
     **/
    private void disconnect() {
        FTPClient client = ftpClient;
        if (null != client && client.isConnected()) {
            try {
                client.logout();
                client.disconnect();
            } catch (IOException ex) {
                logger.error("FTP释放链接时,发生异常,异常信息为:{}", ex.getMessage());
            }
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        final FTP ftp = new FTP();
        ftp.setHost("localhost").
                setPort(21).
                setUsername("hgp").
                setPassword("123456").
                setFtpFolder("/root/").
                setLocalFolder("D:\\ftp\\attachment\\");
        FTPFileSyncTool.syncToFTP(ftp , true);
    }

    public static class FTP {
        private String host;
        private int port = 21;
        private String username;
        private String password;
        /**
         * 需要同步FTP的文件夹
         */
        private String ftpFolder;
        /**
         * 同步到本地的文件夹
         */
        private String localFolder;

        public String getHost() {
            return host;
        }

        public FTP setHost(String host) {
            this.host = host;
            return this;
        }

        public int getPort() {
            return port;
        }

        public FTP setPort(int port) {
            this.port = port;
            return this;
        }

        public String getUsername() {
            return username;
        }

        public FTP setUsername(String username) {
            this.username = username;
            return this;
        }

        public String getPassword() {
            return password;
        }

        public FTP setPassword(String password) {
            this.password = password;
            return this;
        }

        public String getFtpFolder() {
            return ftpFolder;
        }

        public FTP setFtpFolder(String ftpFolder) {
            this.ftpFolder = ftpFolder;
            return this;
        }

        public String getLocalFolder() {
            return localFolder;
        }

        public FTP setLocalFolder(String localFolder) {
            this.localFolder = localFolder;
            return this;
        }
    }

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值