FTP上传下载,防止中文乱码,亲测可用

package com.aa.app.utils;

import com.aa.framework.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

public class FtpUtil {
   private static Log log = LogFactory.getLog(FtpUtil.class);

   /**
    * 维护FTPClient实例
    */
   private final static LinkedBlockingQueue<FTPClient> FTP_CLIENT_QUEUE = new LinkedBlockingQueue<>();

    /***
     * @下载文件夹  递归下载文件夹下所有的文件
     * @param localDirectoryPath本地地址
     * @param remoteDirectory 远程文件夹
     *                        localDirectoryPath  文件下载到本地那个路径
     *                        remoteDirectory  FTP远程路径(需要下载的文件路径)
     *                        downMap  FTP  IP、户名、密码、端口、信息
     *                        bpmCodeList  个人业务需要,可忽略
     * */
    public static boolean downLoadDirectory(String localDirectoryPath, String remoteDirectory, Integer localPassiveMode, List<String> bpmCodeList, Map<String,String> downMap) throws Exception {

        FTPClient ftpClient = null;
        try {
            FtpConfig ftpConfig = new FtpConfig().setUserName(downMap.get("downUserName")).setPassword(downMap.get("downPassword"))
                    .setIp(downMap.get("downUrl")).setPort(Integer.valueOf(downMap.get("downFtpPort")));
            //登录ftp
            ftpClient = connectClient(ftpConfig);
            boolean flag1 = ftpClient.changeWorkingDirectory(remoteDirectory);
            if(!flag1){
                log.error("没有找到" + remoteDirectory + "---该路径");
                return false;
            }
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.setControlEncoding("GBK");
            // 如果FTP支持UTF-8编码,则设置未UTF-8
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
                ftpClient.setControlEncoding("UTF-8");
            }else{
                log.info("sendCommand不支持:sendCommand");
            }
            String fileName = new File(remoteDirectory).getName();
            localDirectoryPath = localDirectoryPath + fileName + "//";
            String localDirectoryPathTmp = localDirectoryPath;
            log.info("文件下载到的路径:" + localDirectoryPath);
            new File(localDirectoryPath).mkdirs();
            if(1 == localPassiveMode){
                ftpClient.enterLocalPassiveMode();//被动模式
            }
            FTPFile[] allFile = ftpClient.listFiles();
            if(allFile == null || allFile.length ==0){
                log.info("远程文件夹不存在或者里面没有文件:" + remoteDirectory);
            }
            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
            if(allFile[currentFile].getName().startsWith(".")){
               log.info("遍历到无用文件,名称为:" + allFile[currentFile].getName());
               continue;
            }
                //如果不是文件夹则下载
                if (!allFile[currentFile].isDirectory()) {
                    log.info("原文件名称:"+allFile[currentFile].getName());
                   
                    downloadTwo(ftpClient,remoteDirectory,allFile[currentFile].getName(),localDirectoryPath + allFile[currentFile].getName(), localPassiveMode);
                    localDirectoryPath = localDirectoryPathTmp;
                }
            }
            //如果是文件夹则继续执行找文件
            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
            if(allFile[currentFile].getName().startsWith(".")){
               log.info("遍历到无用文件夹,名称为:" + allFile[currentFile].getName());
               continue;
            }
                if (allFile[currentFile].isDirectory()) {
                    log.info("是文件夹名字:" + allFile[currentFile].getName());
                    //保存文件夹名字
                    bpmCodeList.add(allFile[currentFile].getName());
                    String strremoteDirectoryPath = remoteDirectory + "/"+ allFile[currentFile].getName();
                    downLoadDirectory(localDirectoryPath,strremoteDirectoryPath,localPassiveMode,bpmCodeList,downMap);
                }
            }
        }catch (Exception e) {
            log.error("下载文件夹失败" + ExceptionUtils.getFullStackTrace(e));
            log.info("下载文件夹失败");
            return false;
        }finally {
            try {
                // 退出FTP
                ftpClient.logout();
                // 归还对象
                ftpClient.disconnect();
            } catch (Exception e) {
                throw new Exception("关闭FTP连接发生异常!", e);
            }
        }
        return true;
    }

    /**
     * 下载文件
     *
     * @param ftpConfig
     *            配置
     * @param remotePath
     *            远程目录
     * @param fileName
     *            文件名
     * @param localPath
     *            本地目录+本地文件名
     *
     * @return 是否下载成功
     */
    private static boolean downloadTwo(FTPClient ftpClient, String remotePath,
                                   String fileName, String localPath,Integer localPassiveMode) throws Exception {

        OutputStream outputStream = null;
        try {
            ftpClient.changeWorkingDirectory(remotePath);
            File file = new File(localPath);
            if (!file.getParentFile().exists()) {
                boolean mkdirsResult = file.getParentFile().mkdirs();
                if (!mkdirsResult) {
                    throw new Exception("创建目录失败");
                }
            }
            if (!file.exists()) {
                boolean createFileResult = file.createNewFile();
                if (!createFileResult) {
                    throw new Exception("创建文件失败");
                }
            }
            if(1 == localPassiveMode){
                ftpClient.enterLocalPassiveMode();//被动模式
            }
            outputStream = new FileOutputStream(file);
            // 文件名称用UTF-8编码  不然文件名称中文乱码
            boolean result1 = ftpClient.retrieveFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"), outputStream);

            outputStream.flush();

            log.info("下载成功,远程文件夹:" + remotePath + ",本地文件夹路径:" + localPath + ",文件名称"+fileName);

        } catch (Exception e) {
            log.error("下载失败" + ExceptionUtils.getFullStackTrace(e));
            throw new Exception(e);
        } finally {
            try {
                outputStream.close();
            } catch (Exception e1) {
                log.error(e1.getMessage(), e1);
            }
        }
        return true;
    }

    /***
     * @上传文件夹  将本地文件夹下所有文件上传到FTP
     * @param localDirectory
     *            当地文件夹
     * @param remoteDirectoryPath
     *            Ftp 服务器路径 以目录"/"结束
     * */
    public static boolean uploadDirectory(String localDirectory,String remoteDirectoryPath,Integer localPassiveMode,Map<String,String> uploadMap,String bpmCode) throws Exception {

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String dateStr = format.format(new Date());

        FTPClient ftpClient = null;
        File src = new File(localDirectory);
        try {
            FtpConfig ftpConfig = new FtpConfig().setUserName(uploadMap.get("uploadUserName")).setPassword(uploadMap.get("uploadPassWord"))
                    .setIp(uploadMap.get("uploadUrl")).setPort(Integer.valueOf(uploadMap.get("uploadFtpPort")));
            //登录ftp
            ftpClient = FtpUtil.connectClient(ftpConfig);
            ftpClient.changeWorkingDirectory(remoteDirectoryPath);
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.setControlEncoding("GBK");
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
                ftpClient.setControlEncoding("UTF-8");
            }else{
                log.info("sendCommand不支持:sendCommand");
            }
            if(1 == localPassiveMode){
                ftpClient.enterLocalPassiveMode();//被动模式
            }
            // 创建一级目录
            ftpClient.makeDirectory(remoteDirectoryPath);
            ftpClient.changeWorkingDirectory(remoteDirectoryPath);
            // 创建二级目录  --日期
            remoteDirectoryPath =  remoteDirectoryPath + "/" +dateStr;
            ftpClient.makeDirectory(remoteDirectoryPath);
            ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
            // 创建三级目录  --bpm单号
            remoteDirectoryPath =  remoteDirectoryPath + "/" +bpmCode;
            ftpClient.makeDirectory(remoteDirectoryPath);
            ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
//            remoteDirectoryPath = remoteDirectoryPath + src.getName() + "/";
//            ftpClient.makeDirectory(remoteDirectoryPath);
//            ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
            log.info("文件上传远程FTP路径 : " + remoteDirectoryPath);
            File[] allFile = src.listFiles();
            if(allFile == null || allFile.length ==0){
                log.info("本地文件夹不存在或者里面没有文件:" + localDirectory);
            }
            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
                if (!allFile[currentFile].isDirectory()) {
                    String srcName = allFile[currentFile].getPath().toString();
                    uploadFile(ftpClient,new File(srcName), remoteDirectoryPath);
                }
            }
            for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
                if(allFile[currentFile].getName().startsWith(".")){
                    log.info("遍历到无用文件夹,名称为:" + allFile[currentFile].getName());
                    continue;
                }
                if (allFile[currentFile].isDirectory()) {
                    // 递归
                    uploadDirectory(allFile[currentFile].getPath().toString(),
                            remoteDirectoryPath,localPassiveMode,uploadMap,bpmCode);
                }
            }
        }catch (IOException e) {
            e.printStackTrace();
            log.info(remoteDirectoryPath + "异常");
        }finally {
            try {
                // 退出FTP
                ftpClient.logout();
                // 归还对象
                ftpClient.disconnect();
            } catch (Exception e) {
                throw new Exception("关闭FTP连接发生异常!", e);
            }
        }
        return true;
    }

    /***
     * 上传Ftp文件
     * @param localFile 当地文件
     * @param romotUpLoadePath上传服务器路径 - 应该以/结束
     * */
    public static boolean uploadFile(FTPClient ftpClient,File localFile, String romotUpLoadePath) {
        BufferedInputStream inStream = null;
        boolean success = false;
        try {
            ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
            inStream = new BufferedInputStream(new FileInputStream(localFile));
            log.info(localFile.getName() + "开始上传.....");
            log.info(new String(localFile.getName().getBytes("UTF-8"),"iso-8859-1") + "开始上传11");
            log.info(new String(localFile.getName().getBytes("GBK"),"iso-8859-1") + "开始上传12");
//            success = ftpClient.storeFile(localFile.getName(), inStream);

//            log.info("1"+ success);
//            success = ftpClient.storeFile(new String(localFile.getName().getBytes("GBK"),"iso-8859-1"), inStream);
//            log.info("2"+ success);
            success = ftpClient.storeFile(new String(localFile.getName().getBytes("UTF-8"),"iso-8859-1"), inStream);
            log.info("3"+ success);

            if (success == true) {
                log.info(localFile.getName() + "上传成功");
                return success;
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
            log.error(localFile + "未找到");
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (inStream != null) {
                try {
                    inStream.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return success;
    }

   /**
    * 登录ftp
    *
    * @param ftpConfig
    *            配置
    * @return 是否登录成功
    * @throws IOException
    */
   public static FTPClient connectClient(FtpConfig ftpConfig)
         throws Exception {
      FTPClient ftpClient = getClient();
      // 连接FTP服务器
      ftpClient.connect(ftpConfig.ip, ftpConfig.port);
      // 登录FTP
      ftpClient.login(ftpConfig.userName, ftpConfig.password);
      // 正常返回230登陆成功
      int reply = ftpClient.getReplyCode();
      if (!FTPReply.isPositiveCompletion(reply)) {
         ftpClient.disconnect();
         throw new Exception("连接ftp失败");
      }
      ftpClient.setControlEncoding("GBK");
      return ftpClient;
   }

   /**
    * 获取ftpClient对象
    *
    * @return 获取client对象
    */
   private static FTPClient getClient() {
      // FTPClient ftpClient = FTP_CLIENT_QUEUE.poll();
      // if (ftpClient != null) {
      // return ftpClient;
      // }
      return new FTPClient();
   }

   private static void offer(FTPClient ftpClient) {
      FTP_CLIENT_QUEUE.offer(ftpClient);
   }

   /**
    * 连接ftp配置
    */
   public static class FtpConfig {
      private String ip;
      private int port;
      private String userName;
      private String password;

      public FtpConfig setIp(String ip) {
         this.ip = ip;
         return this;
      }

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

      public FtpConfig setUserName(String userName) {
         this.userName = userName;
         return this;
      }

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

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值