ftp上傳下載文件/文件夾工具類

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.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.SocketException;

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();
            // 連接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.changeWorkingDirectory(ftpPath);

            File localFile = new File(localPath + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            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("UTF-8");
            // 使用二進制保存方式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            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) {
        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) {
        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.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpFromPath);

            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (int i = 0; i < ftpFiles.length; i++) {
                if (!ftpFiles[i].isDirectory()) {
                    String name = ftpFiles[i].getName();
                    if (flag) {
                        File file = new File(localPath + "\\" + name);
                        if (file != null) {
                            file.delete();
                        }

                    }
                    downloadFtpFile(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort, ftpFromPath, localPath, name);
                }
            }
            for (int i = 0; i < ftpFiles.length; i++) {
                if (ftpFiles[i].isDirectory()) {
                    StringBuilder stringBuilder = new StringBuilder(ftpFromPath);
                    stringBuilder.append("\\").append(ftpFiles[i].getName());
                    ftpFromPath = stringBuilder.toString();
                    if (flag) {
                        File file = new File(localPath + "\\" + ftpFiles[i].getName());
                        if (file != null) {
                            FileUtils.deleteDirectory(file);
                        }

                    }

                    downloadFolder(ftpFromHost, ftpFromUserName, ftpFromPassword, ftpFromPort, ftpFromPath, 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) {

      
    }

    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("UTF-8");
            // 使用二進制保存方式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpToPath = ftpToPath + "\\" + file.getName();
            ftpClient.makeDirectory(ftpToPath);
            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;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章