FTP文件服务器工具类

package com.nuzar.fcms.accept.util.ftp;

import com.jcraft.jsch.*;
import com.nuzar.cloud.common.exception.BizException;
import com.nuzar.cloud.common.utils.StringUtils;
import com.nuzar.fcms.accept.config.FtpConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Random;
import java.util.*;

@Slf4j
public class SftpUtils {
    private Channel channel;
    private Session session;
    private ChannelSftp sftp;

    public static SftpUtils newInstance() {
        return new SftpUtils();
    }


    public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout) {
        return getChannel(ftpHost, port, ftpUserName, ftpPassword, timeout, 3);
    }

    public ChannelSftp getChannel(FtpConfigProperties ftpConfig, int timeout, int times) throws JSchException {
        return getChannel(ftpConfig.getIp(), ftpConfig.getPort(), ftpConfig.getUsername(), ftpConfig.getUserpwd(), timeout, times);
    }

    public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout, int times) {
        int connectTimes = 0;
        while (sftp == null && connectTimes < times) {
            connectTimes++;
            try {
                sftp = getChannel(ftpHost, port, ftpUserName, ftpPassword, timeout, "no");
                log.info("连接SFTP = >> 连接成功");
            } catch (Exception e) {
                try {
                    log.info("连接SFTP = >> 连接不成功,开始重连...");
                    Thread.sleep(100 * new Random().nextInt(100));
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sftp;
    }


    public ChannelSftp getChannel(String ftpHost, int port, String ftpUserName, String ftpPassword, int timeout, String strictHostKeyChecking) throws JSchException {
        JSch jsch = new JSch();
        session = jsch.getSession(ftpUserName, ftpHost, port);
        if (ftpPassword != null) {
            session.setPassword(ftpPassword);
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", strictHostKeyChecking);
        session.setConfig(config);
        session.setTimeout(timeout);
        session.connect();
        log.info("jsch Session connected.");
        channel = session.openChannel("sftp");
        channel.connect();
        log.info("jsch Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName);
        return (ChannelSftp) channel;
    }


    public void uploadFile(InputStream inputStream, String originName, String remoteDir) {
        try {
            sftp.cd("/");
            isRemoteDirExist(remoteDir);
            sftp.put(inputStream, originName);
            log.info("SFTP =>> 文件 {} 上传完成", originName);
        } catch (SftpException e) {
            log.info("SFTP 文件上传失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
        }

    }

    public InputStream getDownloadFileStream(String originName, String remoteDir) {
        try {
            sftp.cd(remoteDir);
            log.info("SFTP =>> 文件 {} 下载", originName);
            return sftp.get(originName);
        } catch (SftpException e) {
            log.info("SFTP 文件下载失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
            throw new BizException(e);
        }
    }

    public String readFile(String originName, String remoteDir) {
        BufferedReader bufferedReader = null;
        StringBuilder content = new StringBuilder("");
        try {
            sftp.cd(remoteDir);//进入指定目录操作
            InputStream inputStream = sftp.get(originName);
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            String tempString = null;
            while ((tempString = bufferedReader.readLine()) != null) {
                content.append(tempString);
            }
            return content.toString();
        } catch (Exception e) {
            log.info("SFTP 文件读取失败 ,路径[" + remoteDir + "],文件名 [" + originName + "]", e.getMessage());
            throw new BizException(e);
        } finally {
            try {
                if (bufferedReader != null)
                    bufferedReader.close();//关闭流
            } catch (IOException e) {
                log.error("Close BufferedReader error:", e);
            }
        }

    }

    public void isRemoteDirExist(String remoteDir) {
        try {
            sftp.cd(remoteDir);
        } catch (SftpException e) {
            try {
                String[] dirs = remoteDir.split("/");
                for (String dir : dirs) {
                    if (StringUtils.isEmpty(dir)) {
                        continue;
                    }
                    try {
                        sftp.cd(dir);
                    } catch (SftpException e1) {
                        log.info("上传SFTP =>> 目录[" + dir + "]不存在,开始创建");
                        sftp.mkdir(dir);
                        log.info("上传SFTP =>> 目录[" + dir + "],目录创建成功,进入目录");
                        sftp.cd(dir);
                    }
                }
            } catch (SftpException ex) {
                log.info("上传SFTP失败:{}", e.getMessage());
            }
        }
    }

    public void renameFile(String oldpath, String newpath) {
        try {
            sftp.rename(oldpath, newpath);
            log.info("SFTP =>> 文件 {} 重命名完成", newpath);
        } catch (SftpException e) {
            log.info("SFTP 文件重命名失败 ,oldpath [" + oldpath + "],newpath [" + newpath + "]", e.getMessage());
        }
    }

    public void delFileNow(String filePath) {
        try {
            if (isDir(filePath)) {
                sftp.cd(filePath);
                Vector<ChannelSftp.LsEntry> entries = sftp.ls(filePath);
                for (ChannelSftp.LsEntry entry : entries) {
                    if (entry.getFilename().equals(".") || entry.getFilename().equals("..")) {
                        continue;
                    }
                    delFile(filePath + "/" + entry.getFilename());
                }
            } else {
                sftp.rm(filePath);
            }
        } catch (SftpException e) {
            e.printStackTrace();
            log.info("SFTP 删除文件 [" + filePath + "]失败", e.getMessage());
        }
    }

    public void delFile(String filePath) {
        try {
            if (isDir(filePath)) {
                sftp.cd(filePath);
                Vector<ChannelSftp.LsEntry> entries = sftp.ls(filePath);
                for (ChannelSftp.LsEntry entry : entries) {
                    if (entry.getFilename().equals(".") || entry.getFilename().equals("..")) {
                        continue;
                    }
                    delFile(filePath + "/" + entry.getFilename());
                }
            } else {
                SftpATTRS sftpATTRS = sftp.lstat(filePath);
                Date date = new Date((long) sftpATTRS.getMTime() * 1000L);
                LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
                LocalDateTime dateTime = LocalDateTime.now().plusDays(-7);
                if (dateTime.isAfter(localDateTime)) {
                    log.info("SFTP 文件清理 =>> 删除7天前的文件[" + filePath + "]");
                    sftp.rm(filePath);
                }
            }
        } catch (SftpException e) {
            e.printStackTrace();
            log.info("SFTP 删除文件 [" + filePath + "]失败", e.getMessage());
        }
    }


    public boolean isDir(String filePath) {
        try {
            return sftp.stat(filePath).isDir();
        } catch (SftpException e) {
            e.printStackTrace();
        }
        return false;
    }

    public List<String> listDir(String filePath) {
        List<String> fileNames = Lists.newArrayList();
        try {
            Vector<ChannelSftp.LsEntry> ls = sftp.ls(filePath);
            for (ChannelSftp.LsEntry l : ls) {
                //移除上级目录和根目录:"." ".."
                if (".".equals(l.getFilename()) || "..".equals(l.getFilename())) {
                    continue;
                }
                String filename = l.getFilename();
                fileNames.add(filename);
            }
        } catch (SftpException e) {
            log.error("ls directory fail", e);
        }
        return fileNames;
    }

    public void closeChannel() {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
        log.info("SFTP =>> 连接关闭");
    }

    public static void main(String[] args) {
        SftpUtils channel = SftpUtils.newInstance();
        ChannelSftp sftp = channel.getChannel("192.168.20.36", 22, "root", "Gx#P@ssw0rd", 1000);
        if (sftp == null) {
            return;
        }
        try {
            //InputStream inputStream =  new FileInputStream(new File("D:\\migration-tool-package.zip"));
            //channel.uploadFile(inputStream,"migration-tool-package.zip","/home/aaaaa/bbbb");
            //channel.renameFile("/home/aaaa/bbbbb/test.csv.tmp", "/home/aaaa/bbbbb/test.csv");
            channel.delFile("/home/aaaa");
            channel.closeChannel();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

示例:

 /**
     * 扫描并处理计划
     */
    @Override
    public void scanFtpFiles() {
        SftpUtils utils = SftpUtils.newInstance();
        try {
            ChannelSftp channel = utils.getChannel(ftpConfigProperties, 3000, 3);
            if (Objects.isNull(channel)) {
                log.error("通道建立失败,无法处理EDI目录文件");
                return;
            }
            List<String> fileNames = utils.listDir(ftpConfigProperties.getBasedir());
            for (String fileName : fileNames) {
                try {
                    log.info("load file:{}", fileName);
                    String content = utils.readFile(fileName, ftpConfigProperties.getBasedir());
                    if (processEdiDoc(content)) {
                        log.info("success process file {}", fileName);
                    } else {
                        log.info("failed process file {}", fileName);
                    }
                    log.info("del file:{}", fileName);
                    utils.delFileNow(ftpConfigProperties.getBasedir() + File.separator + fileName);
                    log.info("finish file:{}", fileName);
                } catch (Throwable t) {
                    log.error("biz error", t);
                }
            }
        } catch (JSchException e) {
            log.error("sftp error", e);
            throw new BizException(e);
        } finally {
            utils.closeChannel();
        }
    }
package com.nuzar.fcms.accept.config;

import com.jcraft.jsch.ChannelSftp;
import com.nuzar.fcms.accept.util.ftp.SftpUtils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "accept-service.edi.ftp")
public class FtpConfigProperties {
    /**
     * 登录信息
     */
    private String ip;
    private Integer port;
    private String basedir;

    /**
     * 用户信息
     */
    private String username;
    private String userpwd;


    @Bean
    public ChannelSftp ftpServer() {
        SftpUtils utils = SftpUtils.newInstance();
        // return utils.getChannel(ip, port, username, userpwd, 3000);
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值