Java 需求:项目使用网络协议从FTP更换成SFTP

公司项目的代码用的是Hutool的FTP类进行操作,进行了大量的封装,使用起来确实简单,但它的SFTP类没找到Api手册,所以网上百度修改了工具类,使用 com.jcraft.jsch 进行开发

依赖

        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.55</version>
        </dependency>

配置类

@Data
@ConfigurationProperties(prefix = "media.ftp")
@Component
public class FtpConfig {
    //匿名登录(无需帐号密码的FTP服务器)
//    @Value("${media.ftp.ip:127.0.0.1}")
    private String ip;
    //    @Value("${media.ftp.port:21}")
    private Integer port;
    //    @Value("${media.ftp.username:}")
    private String username;
    //    @Value("${media.ftp.password:}")
    private String password;
    /**
     * 默认再ftp跟目录
     */
    private String path = "";

    /**
     * 默认再ftp跟目录
     */
    private String sftp_path;
    private Integer sftp_port;
    private String sftp_username;
    private String sftp_password;
}

提示枚举类

package com.lx.xvep.media.common;
public enum FtpErrorCode {
    CONNECT_SERVER_FAILER("连接sftp服务器失败"),
    DISCONNECT_SERVER_GET_CONNECT_FAILER("断开sftp服务器获取连接失败"),
    CREATE_DIRECTORY_FAILER("创建SFTP目录失败"),
    GET_LOCAL_FILE_INPUT_STREAM("获取本地文件输入流失败"),
    UPLOAD_FILE_FAILER("上传文件失败"),
    GET_LOCAL_FILE_OUTPUT_STREAM("获取本地输出流失败"),
    DELETE_FTP_FILE_FAILER("删除FTP文件失败"),
    CD_REMOTE_PATH_FAILER("进入远程目录失败"),
    LS_REMOTE_PATH_FAILER("进入远程目录失败");

    private String errorDesc;


    FtpErrorCode(String errorDesc) {
        this.errorDesc = errorDesc;
    }

    public String getErrorDesc() {
        return errorDesc;
    }

    public void setErrorDesc(String errorDesc) {
        this.errorDesc = errorDesc;
    }
}

SFTP操作工具类 包含常用的获取Session、关闭session、上传、下载、查询目录是否存在、创建目录等操作

package com.lx.xvep.media.utils;

import com.jcraft.jsch.*;
import com.lx.xvep.media.common.FtpErrorCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

/**
 *
 */
public class SFTPUtils {
    private final static Logger logger = LoggerFactory.getLogger(SFTPUtils.class);

    private final static int CLIENT_TIMEOUT = 3600* 1000;

    ChannelSftp channelSftp = null;     //所有操作公用一个Channel
    private String serverIP;
    private Integer	port ;
    private String username;
    private String password;
    private String encoding = "UTF-8";

    public SFTPUtils(String serverIP, Integer port, String username, String password){
        this.serverIP = serverIP;
        if(port!=null){
            this.port = port;
        }
        this.username = username;
        this.password = password;
    }

    public static SFTPUtils newInstance(String serverIP, Integer port, String username, String password) {
        return new SFTPUtils(serverIP,port,username,password);
    }

    /**
     * (50+50) * 0.05 = 50* 0.05 + 50* 0.05
     * @return
     */
    public void connectFtp() throws Exception{
        logger.info("SftpUtils start beginning");
        Session session = null;
        try {
            JSch jSch = new JSch();
            session = jSch.getSession(username,serverIP,port);
            session.setTimeout(CLIENT_TIMEOUT);
            if(! StringUtils.isEmpty(password)){
                session.setPassword(password);
            }
            Properties properties = new Properties();
            properties.setProperty("StrictHostKeyChecking","no");
            session.setConfig(properties);
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();

            channelSftp = (ChannelSftp)channel;

        }catch (Exception e){
            logger.info(FtpErrorCode.CONNECT_SERVER_FAILER.getErrorDesc());
            throw e;
        }
    }


    public void disConnect() throws Exception{
        logger.info("SftpUtils end beginning...");
        if(channelSftp != null){
            Session session= null;
            try {
                session = channelSftp.getSession();
            }catch (JSchException e){
                logger.info(FtpErrorCode.DISCONNECT_SERVER_GET_CONNECT_FAILER.getErrorDesc());
                throw e;
            }finally {
                if(session !=null){
                    session.disconnect();
                }
            }
        }
    }




    /**
     * 将输入流上传到SFTP服务器,作为文件
     *
     * @param directory     上传到SFTP服务器的路径
     * @param sftpFileName  上传到SFTP服务器后的文件名
     * @param input         输入流
     * @throws SftpException
     */
    public boolean upload(String directory, String sftpFileName, InputStream input) throws Exception {
        this.connectFtp();
        long start = System.currentTimeMillis();
        try {
            //如果文件夹不存在,则创建文件夹
            if (channelSftp.ls(directory) == null) {
                channelSftp.mkdir(directory);
            }
            //切换到指定文件夹
            channelSftp.cd(directory);
        } catch (SftpException e) {
            //创建不存在的文件夹,并切换到文件夹
            channelSftp.mkdir(directory);
            channelSftp.cd(directory);
            return false;
        }
        try{
            channelSftp.put(input, sftpFileName);
        }finally {
            this.disConnect();
        }
        logger.info("文件上传成功!! 耗时:{}ms", (System.currentTimeMillis() - start));
        return true;
    }

    /**
     * 创建一个文件目录
     *
     * @param createpath        路径
     * @return
     */
    public boolean mkdirs(String createpath) throws Exception {
        try {
            this.connectFtp();
            if (exist(createpath)) {
                this.channelSftp.cd(createpath);
                return true;
            }
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (exist(filePath.toString())) {
                    channelSftp.cd(filePath.toString());
                } else {
                    // 建立目录
                    channelSftp.mkdir(filePath.toString());
                    // 进入并设置为当前目录
                    channelSftp.cd(filePath.toString());
                }
            }
            this.channelSftp.cd(createpath);
        } catch (SftpException e) {
            logger.error("目录创建异常!", e);
            return false;
        }finally {
            this.disConnect();
        }
        return true;
    }



    /**
     * 判断目录是否存在
     * @param remoteDirectory               /abc/sdf/sdf/adf
     */
    public boolean exist(String remoteDirectory) throws Exception {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = this.channelSftp.lstat(remoteDirectory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;

    }

    /**
     * @param remoteFile   远程文件————————>本系统特点是从一个目录取得
     * @param localFile    本地系统目录
     */
    public void ftpDownLoad(String remoteFile,String localFile) throws Exception{
        logger.info("SftpUtils download beginning");
        logger.info("1. 连接ftp服务器");
        this.connectFtp();
        logger.info("2. 创建本地文件输入流");
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(localFile);
        } catch (FileNotFoundException e) {
            this.disConnect();
            logger.info(FtpErrorCode.GET_LOCAL_FILE_OUTPUT_STREAM.getErrorDesc());
            throw new RuntimeException(e);
        }
        logger.info("3. 下载到本地文件/输出流");
        try {
            channelSftp.get(remoteFile.replaceAll("\\\\","/"),outputStream);
        } catch (SftpException e) {
            this.disConnect();
            logger.info(FtpErrorCode.GET_LOCAL_FILE_OUTPUT_STREAM.getErrorDesc());
            throw e;
        }finally {
            logger.info("4. 关闭sftp的连接");
            this.disConnect();
        }
    }


    //读取远程文件中的内容,并返回流  remoteFile:远程文件全路径 如:download/sds.csv
    public InputStream sftpWriter(String remoteFile){

        InputStream is=null;
        try {
            logger.info("SftpUtils download beginning");
            logger.info("1. 连接ftp服务器");
            this.connectFtp();
            logger.info("2. 创建远程文件输出流");
            is = channelSftp.get(remoteFile);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (SftpException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                logger.info("3. 关闭sftp的连接");
                this.disConnect();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return is;

    }


    public void ftpDelete(String remoteFile) throws Exception{
        logger.info("SftpUtils download beginning");
        logger.info("1. 连接ftp服务器");
        this.connectFtp();
        logger.info("2. 删除远端文件");
        String directory = remoteFile.replaceAll("\\\\","/").substring(0,remoteFile.lastIndexOf("/"));
        try {
            channelSftp.cd(directory);
        } catch (SftpException e) {
            this.disConnect();
            logger.info(FtpErrorCode.DELETE_FTP_FILE_FAILER.getErrorDesc());
            throw e;
        }
//        String fileName = remoteFile.substring(remoteFile.replaceAll("\\\\","/").lastIndexOf("/") + 1);
        try {
            channelSftp.rm(remoteFile);//remove()
        } catch (SftpException e) {
            this.disConnect();
            logger.info(FtpErrorCode.DELETE_FTP_FILE_FAILER.getErrorDesc());
            throw e;
        }finally {
            logger.info("4. 关闭sftp的连接");
            this.disConnect();
        }
    }

    /**
     * 查找目录下的所有文件
     * @param remoteFileDirectory
     * @return
     */
    public List<String> findFiles(String remoteFileDirectory) throws Exception{
        logger.info("find directory files beginning...");
        List<String> listFile = new ArrayList<String>();
        logger.info("1. 连接ftp服务器");
        this.connectFtp();

        logger.info("2. 效验远程目录");
        logger.info("远程目录为:"+remoteFileDirectory);
        try {
            channelSftp.cd(remoteFileDirectory.replaceAll("\\\\","/"));
        } catch (SftpException e) {
            mkdirs(remoteFileDirectory.replaceAll("\\\\","/"));
            return listFile;
        }

        logger.info("3. 查找文件名称");
        Vector<?> vector = null;
        try {
            vector = channelSftp.ls(remoteFileDirectory.replaceAll("\\\\","/"));
            for(Object obj : vector){
                if(obj != null){
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry)obj;
                    if(!entry.getAttrs().isDir() ){
                        listFile.add(entry.getFilename());
                    }
                }
            }
        } catch (SftpException e) {
            logger.info(FtpErrorCode.LS_REMOTE_PATH_FAILER.getErrorDesc());
            throw e;
        }finally {
            this.disConnect();
        }
        return listFile;
    }

    public List<String> findFilesLength10(String remoteFileDirectory) throws Exception{
        logger.info("find directory files beginning...");
        List<String> listFile = new ArrayList<String>();
        logger.info("1. 连接ftp服务器");
        this.connectFtp();

        logger.info("2. 效验远程目录");
        logger.info("远程目录为:"+remoteFileDirectory);
        try {
            channelSftp.cd(remoteFileDirectory.replaceAll("\\\\","/"));
        } catch (SftpException e) {
            mkdirs(remoteFileDirectory.replaceAll("\\\\","/"));
            return listFile;
        }

        logger.info("3. 查找文件名称");
        Vector<?> vector = null;
        try {
            vector = channelSftp.ls(remoteFileDirectory.replaceAll("\\\\","/"));
            for(Object obj : vector){
                if(obj != null){
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry)obj;
                    if(!entry.getAttrs().isFifo() && entry.getFilename().length() == 10){
                        listFile.add(entry.getFilename());
                    }
                }
            }
        } catch (SftpException e) {
            logger.info(FtpErrorCode.LS_REMOTE_PATH_FAILER.getErrorDesc());
            throw e;
        }finally {
            this.disConnect();
        }
        return listFile;
    }

    /*
     * 获取ftp服务器下某个文件下的  符合条件的文件
     * */
    public List<String> findConditionFiles(String sftpPath) throws Exception {

        //获取文件夹中的  所有符合条件文件
        logger.info("find directory files beginning...");
        List<String> listFile = new ArrayList<String>();
        logger.info("1. 连接ftp服务器");
        try {
            this.connectFtp();
        } catch (Exception e) {
            e.printStackTrace();
        }

        logger.info("2. 效验远程目录");
        logger.info("远程目录为:"+sftpPath);
        try {
            channelSftp.cd(sftpPath.replaceAll("\\\\","/"));
        } catch (SftpException e) {
            mkdirs(sftpPath.replaceAll("\\\\","/"));
            return listFile;
        }

        logger.info("3. 查找文件名称");
        Vector<?> vector = null;
        try {
            vector = channelSftp.ls(sftpPath.replaceAll("\\\\","/"));
            for(Object obj : vector){
                if(obj != null){
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry)obj;
                    if(!entry.getAttrs().isDir()){
                        String filename = entry.getFilename();
                        if ("sendnumber_202".equals(filename.trim().substring(0,14))){
                            listFile.add(filename);
                            logger.info("有效CSV同步的文件为:"+filename);
                        }
                    }
                }
            }
        } catch (SftpException e) {
            logger.info(FtpErrorCode.LS_REMOTE_PATH_FAILER.getErrorDesc());
            throw e;
        }finally {
            this.disConnect();
        }

        return listFile;
    }

    /**
     * @param srcFile     源文件
     * @param destFile    目标文件
     */
    public void moveFile(String srcFile, String destFile) throws Exception{
        logger.info("1. 连接ftp服务器");
        this.connectFtp();

        logger.info("2. 效验目标文件的目录,如果没有则创建");
        int pos = destFile.lastIndexOf("/");
        this.mkdirs(destFile.substring(0,pos)); // 创建目录

        logger.info("3. 将源文件名称 重命名为 目标文件名称");
        try {
            channelSftp.rename(srcFile.replaceAll("\\\\","/"),destFile.replaceAll("\\\\","/"));
        } catch (SftpException e) {
            e.printStackTrace();
            logger.info(FtpErrorCode.LS_REMOTE_PATH_FAILER.getErrorDesc());
            throw e;
        }finally {
            this.disConnect();
        }
//      logger.info("4. 删除源文件");
//      this.ftpDelete(srcFile.replaceAll("\\\\","/"));
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值