ftp上传下载文件/文件夹工具类

package com.bonc.hamal.swapnode.datax.plugins.utils;

import jdk.internal.dynalink.beans.StaticClass;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
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.*;
import java.net.SocketException;
import java.util.Arrays;

/**
 * @author sz
 * @date 2020/03/03
 */
public class FtpUtil {


    private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);



    /**
     * 获取FTPClient对象
     *
     * @param ftpHost     FTP主机服务器
     * @param ftpPassword FTP 登录密码
     * @param ftpUserName FTP登录用户名
     * @param ftpPort     FTP端口 默认为21
     * @return
     */
    public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
           // ftpClient.setAutodetectUTF8(true);
            // 连接FTP服务器
            ftpClient.connect(ftpHost, ftpPort);
            // 登陆FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
                logger.error("未连接到FTP,用户名或密码错误。");
            } else {
                logger.info("FTP connection success");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            logger.error("FTP的IP地址可能错误,请正确配置。");
        } catch (IOException e) {
            logger.error("FTP的IP地址可能错误,请正确配置。");
        }
        return ftpClient;
    }

    /**
     * 从FTP服务器获取文件
     *
     * @param ftpHost     FTP IP地址
     * @param ftpUserName FTP 用户名
     * @param ftpPassword FTP用户名密码
     * @param ftpPort     FTP端口
     * @param ftpPath     FTP服务器中文件所在路径 格式: /ftptest/aa.pdf
     */
    public static byte[] getFtpFileBytes(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort, String ftpPath) {
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            // 中文支持
            ftpClient.setControlEncoding("UTF-8");
            // 使用二进制保存方式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            /*
             * 这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。
             * 为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,
             * 但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
             */
            ftpClient.enterLocalPassiveMode();
            InputStream inputStream = ftpClient.retrieveFileStream(ftpPath);
            if (null == inputStream) {
                logger.error("没有找到" + ftpPath + "文件");
            }
            byte[] bytes = IOUtils.toByteArray(inputStream);
            inputStream.close();
            ftpClient.logout();
            return bytes;
        } catch (FileNotFoundException e) {
            logger.error("没有找到" + ftpPath + "文件");
        } catch (SocketException e) {
            logger.error("连接FTP失败.");
        } catch (IOException e) {
            logger.error("文件读取错误。");
        }
        return null;
    }

    /**
     * 从FTP服务器下载文件
     *
     * @param ftpHost     FTP IP地址
     * @param ftpUserName FTP 用户名
     * @param ftpPassword FTP用户名密码
     * @param ftpPort     FTP端口
     * @param ftpPath     FTP服务器中文件所在路径 格式: ftptest/aa
     * @param localPath   下载到本地的位置 格式:H:/download
     * @param fileName    文件名称
     */
    public static void downloadFtpFile(String ftpHost, String ftpUserName,
                                       String ftpPassword, int ftpPort, String ftpPath, String localPath,
                                       String fileName) {
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            // 中文支持
            //ftpClient.setControlEncoding("UTF-8");
            // 使用二进制保存方式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();


            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            String dir = new String(ftpPath.getBytes("GBK"), "iso-8859-1");
            ftpClient.changeWorkingDirectory(dir);
            File localFile = new File(localPath + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            ftpClient.retrieveFile(new String(fileName.getBytes("GBK"),"ISO-8859-1"), os);
           // ftpClient.retrieveFile(fileName, os);
            os.close();
            ftpClient.logout();

        } catch (FileNotFoundException e) {
            logger.error("没有找到" + fileName + "文件");
        } catch (SocketException e) {
            logger.error("连接FTP失败.");
        } catch (IOException e) {
            logger.error("文件读取错误。");
        }

    }

    /**
     * Description: 向FTP服务器上传文件
     *
     * @param ftpHost     FTP服务器hostname
     * @param ftpUserName 账号
     * @param ftpPassword 密码
     * @param ftpPort     端口
     * @param ftpPath     FTP服务器中文件所在路径 格式: ftptest/aa
     * @param fileName    ftp文件名称
     * @param input       文件流
     * @param flag       是否覆盖源文件
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String ftpHost, String ftpUserName,
                                     String ftpPassword, int ftpPort, String ftpPath,
                                     String fileName, InputStream input, boolean flag) {
        boolean success = false;
        FTPClient ftpClient = null;
        try {
            int reply;
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return success;
            }

            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 使用二进制保存方式
            ftpClient.enterLocalPassiveMode();

            String dir = new String(ftpPath.getBytes("GBK"), "iso-8859-1");
            ftpClient.changeWorkingDirectory(dir);
            String filePath = ftpPath + File.separator + fileName;
            FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
            if (flag && ftpFiles.length > 0) {
                ftpClient.deleteFile(filePath);

            }
            ftpClient.storeFile(fileName, input);
            input.close();
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * ftp文件系统之间相互转化
     * 将ftp文件下载到本地,然后下载下来.上传到对应的目录中去
     * 最后删除临时文件
     *
     * @param ftpFromHost     文件来源端口
     * @param ftpFromUserName 文件地址
     * @param ftpFromPassword 文件密码
     * @param ftpFromPort     文件来源端口
     * @param localPath       文件缓存地址
     * @param ftpFromPath     文件所在文件夹地址
     * @param fileName        文件名称
     * @param ftpToHost       文件去向地址
     * @param ftpToUserName   文件去向用户密码
     * @param ftpToPassword   文件密码
     * @param ftpToPort       文件去向端口
     * @param ftpToPath       文件去向路径
     * @param ftpToFileName   文件另存为名称
     * @param overrideFlag   文件是否覆盖
     * @return 文件是否交换成功
     */
    public static boolean exchangeFileFromFtpToFtp(String ftpFromHost, String ftpFromUserName,
                                                   String ftpFromPassword, int ftpFromPort, String ftpFromPath,
                                                   String localPath, String fileName,
                                                   String ftpToHost, String ftpToUserName,
                                                   String ftpToPassword, int ftpToPort, String ftpToPath, String ftpToFileName, boolean overrideFlag) {
        boolean flag = false;
        downloadFtpFile(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort, ftpFromPath, localPath, fileName);
        logger.error("文件交换之下载成功");
        String filePath = localPath + File.separator + fileName;
        File file = new File(filePath);
        try {
            InputStream inputStream = new FileInputStream(file);
            flag = uploadFile(ftpToHost, ftpToUserName,
                    ftpToPassword, ftpToPort, ftpToPath,
                    ftpToFileName, inputStream, overrideFlag);
        } catch (FileNotFoundException e) {
            logger.error("文件上传异常{}", e.toString());
        } finally {
            file.delete();
        }
        return flag;
    }

    /**
     * @param ftpFromHost
     * @param ftpFromUserName
     * @param ftpFromPassword
     * @param ftpFromPort
     * @param ftpFromPath
     * @param localPath
     * @param overrideFlag    文件是否覆盖
     * @param ftpToHost
     * @param ftpToUserName
     * @param ftpToPassword
     * @param ftpToPort
     * @param ftpToPath
     * @return
     */
    public static boolean exchangeFolderFromFtpToFtp(String ftpFromHost, String ftpFromUserName,
                                                     String ftpFromPassword, int ftpFromPort, String ftpFromPath,
                                                     String localPath, String folderName, boolean overrideFlag,
                                                     String ftpToHost, String ftpToUserName,
                                                     String ftpToPassword, int ftpToPort, String ftpToPath) throws InterruptedException {
        boolean flag = false;
        downloadFolder(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort, ftpFromPath, localPath, overrideFlag);
        logger.error("文件交换之下载成功");
        String filePath = localPath + File.separator + folderName;
        File file = new File(filePath);
        try {
            flag = uploadDirectory(ftpToHost, ftpToUserName, ftpToPassword, ftpToPort, ftpToPath, filePath, overrideFlag);
        } catch (Exception e) {
            logger.error("文件上传异常{}", e.toString());
        } finally {
            try {
                FileUtils.deleteDirectory(file);
            } catch (IOException e) {
                logger.error("文件删除异常{}", e.toString());
            }
        }
        return flag;
    }

    /**
     * 从ftp服务器中下载文件夹到本地
     *
     * @param ftpFromHost
     * @param ftpFromUserName
     * @param ftpFromPassword
     * @param ftpFromPort
     * @param ftpFromPath
     * @param localPath
     * @param flag            是否覆盖源文件
     * @return
     */
    public static boolean downloadFolder(String ftpFromHost, String ftpFromUserName,
                                         String ftpFromPassword, int ftpFromPort, String ftpFromPath, String localPath, boolean flag) throws InterruptedException {
        FTPClient ftpClient = null;
        String fileName = new File(ftpFromPath).getName();
        localPath = localPath + "\\" + fileName;
        new File(localPath).mkdirs();
        try {
            ftpClient = getFTPClient(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort);
            // 中文支持
           // ftpClient.setControlEncoding("UTF-8");
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            String dir = new String(ftpFromPath.getBytes("GBK"), "iso-8859-1");

            // 使用二进制保存方式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(dir);
          //  Thread.sleep(10000);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (int i = 0; i < ftpFiles.length; i++) {
                FTPFile ftpFile = ftpFiles[i];
                String name = ftpFile.getName();
                if (!ftpFile.isDirectory()) {
                    if (flag) {
                        File file = new File(localPath + "\\" + name);
                        if (file != null) {
                            file.delete();
                        }

                    }
                    downloadFtpFile(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort, ftpFromPath, localPath, name);
                }else{

                    downloadFolder(ftpFromHost,ftpFromUserName,ftpFromPassword,ftpFromPort,ftpFromPath+"/"+name,localPath,flag);
                }
            }
        } catch (FileNotFoundException e) {

            logger.error("没有找到" + ftpFromPath + "文件");
            return false;
        } catch (SocketException e) {
            logger.error("连接FTP失败.");
            return false;
        } catch (IOException e) {
            logger.error("文件读取错误。");
            return false;
        }

        return true;
    }


    public static void main(String[] args) throws Exception {

      /*  File file =new File("E:\\tmp\\DataX-master\\adswriter\\src\\main\\java\\com\\alibaba\\datax\\plugin\\writer\\adswriter");
        try {
            System.out.println(file.getCanonicalPath().toString());
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        uploadDirectory("172.16.74.83", "anonymous", "", 21, "/", "D:\\data01\\DSE", true);
      //  uploadFile("172.16.74.83", "anonymous", "", 21, "/", "E:\\tmp", true)

      //  downloadFolder("172.16.74.83", "anonymous", "89701207", 21, "/", "D:\\tools",true);
        //downloadFtpFile("172.16.74.83","tjs_ftp","ftp%123",21,"/data01/soft/ftp/ik","D:\\tmp","test.csv");

    }

    private static boolean uploadDirectory(String ftpToHost, String ftpToUserName,
                                           String ftpToPassword, int ftpToPort, String ftpToPath, String localPath, boolean flag) {

        FTPClient ftpClient = null;
        File file = new File(localPath);
        if (!file.isDirectory()) {
            System.out.println("该路径不是文件夹路径" + localPath);
        }
        try {
            ftpClient = getFTPClient(ftpToHost, ftpToUserName, ftpToPassword, ftpToPort);
            // 中文支持
            ftpClient.setControlEncoding("GBK");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 使用二进制保存方式
            ftpClient.enterLocalPassiveMode();
            ftpToPath = ftpToPath + "\\" + file.getName();
            String dir = new String(ftpToPath.getBytes("GBK"), "iso-8859-1");
            ftpClient.makeDirectory(dir);
            File[] listFiles = file.listFiles();
            for (int i = 0; i < listFiles.length; i++) {
                if (!listFiles[i].isDirectory()) {
                    InputStream in = new FileInputStream(listFiles[i]);

                    uploadFile(ftpToHost, ftpToUserName, ftpToPassword, ftpToPort, ftpToPath, listFiles[i].getName(), in, flag);
                }
            }
            for (int i = 0; i < listFiles.length; i++) {
                if (listFiles[i].isDirectory()) {

                    if (listFiles[i].getCanonicalPath().contains(localPath)) {
                        StringBuilder stringBuilder = new StringBuilder(localPath);
                        stringBuilder.append("\\").append(listFiles[i].getName());
                        localPath = stringBuilder.toString();
                    } else {
                        localPath = listFiles[i].getParentFile().getCanonicalPath();
                        StringBuilder stringBuilder = new StringBuilder(localPath);
                        stringBuilder.append("\\").append(listFiles[i].getName());
                        localPath = stringBuilder.toString();
                    }
                    uploadDirectory(ftpToHost, ftpToUserName, ftpToPassword, ftpToPort, ftpToPath, localPath, flag);
                }
            }
        } catch (FileNotFoundException e) {
            logger.error("没有找到" + localPath + "文件");
            return false;
        } catch (SocketException e) {
            logger.error("连接FTP失败.");
            return false;
        } catch (IOException e) {
            logger.error("文件读取错误。");
            return false;
        }

        return true;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_39684784/article/details/106171855