ChannelSftp的使用心得

以下为个人使用过程中的心得经验

  • ChannelSftp是Java连接sftp服务器并进行相关操作的核心类,有许多api方法可以使用,以下就本人相关代码进行说明。 ChannelSftp的使用心得
    package com.zxhc.dms.operationalPlan.sync;
    
    import cn.hutool.core.util.ObjectUtil;
    import com.jcraft.jsch.*;
    import lombok.extern.slf4j.Slf4j;
    
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Properties;
    import java.util.Vector;
    
    @Slf4j
    public class FTPUtil {
    
        private ChannelSftp sftp;
        private Session session;
        /** SFTP 登录用户名*/
        private String username;
        /** SFTP 登录密码*/
        private String password;
        /** 私钥 */
        private String privateKey;
        /** SFTP 服务器地址IP地址*/
        private String host;
        /** SFTP 端口*/
        private int port;
        /**默认连接超时*/
        private static Integer timeOut = 20000;
    
        /**文件编码*/
        private static String FILE_CODE = "UTF-8";
    
        /**
         *  构造基于密码认证的sftp对象 <br>
         * @param host 主机 <br>
         * @param port 端口号 <br>
         * @param username 用户名 <br>
         * @param password 密码 <br>
         */
        public FTPUtil(String host, int port, String username, String password) {
            this.username = username;
            this.password = password;
            this.host = host;
            this.port = port;
        }
    
    
    
        /**
         * 连接sftp服务器
         */
        public void login(){
            try {
                JSch jsch = new JSch();
                if (privateKey != null) {
                    jsch.addIdentity(privateKey);// 设置私钥
                }
    
                session = jsch.getSession(username, host, port);
    
                if (password != null) {
                    session.setPassword(password);
                }
                Properties config = new Properties();
                config.put("StrictHostKeyChecking", "no");
    
                session.setConfig(config);
                session.setTimeout(timeOut);
    
                session.connect();
    
                Channel channel = session.openChannel("sftp");
                channel.connect();
    
                sftp = (ChannelSftp) channel;
                sftp.setFilenameEncoding(FILE_CODE);
            } catch (Exception e) {
                e.printStackTrace();
                this.logout();
            }
        }
    
        /**
         * 关闭连接 server
         */
        public void logout(){
            if (ObjectUtil.isNotEmpty(sftp)) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            if (ObjectUtil.isNotEmpty(session)) {
                if (session.isConnected()) {
                    session.disconnect();
                }
            }
        }
    
        /**
         * 将输入流的数据上传到sftp作为文件。
         * @param directory  上传到该目录  <br>
         * @param file   上传文件 <br>
         */
        public boolean uploadFile(String directory, File file, String fileText) throws Exception{
            try {
                log.info("cd===================="+directory);
                sftp.cd(directory);
            } catch (Exception e) {
                //目录不存在,则创建文件夹
                log.info("mkdir===================="+directory);
                sftp.mkdir(directory);
                sftp.cd(directory);
            }
            ByteArrayInputStream stream = new ByteArrayInputStream(fileText.getBytes());
            sftp.put(stream, file.getName());  //上传文件
            stream.close();
            file.delete();  //删除本地文件
            this.logout();
            return true;
        }
    
        /**
         * 删除sftp服务器指定目录下文件夹。
         * @param directory  指定目录<br>
         * @param numDay  指定相差删除天数<br>
         */
        public void delOvertime(String directory, int numDay) throws SftpException {
            //YYYY-MM-DD日期匹配正则
            String rexp1 = "((\\d{2}(([02468][048])|([13579][26]))[\\-]((((0?[13578])|(1[02]))[\\-]((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-]((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-]((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-]((((0?[13578])|(1[02]))[\\-]((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-]((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-]((0?[1-9])|(1[0-9])|(2[0-8]))))))";
            Date currentTime = new Date();
            //获取该目录下所有文件
            Vector S = sftp.ls(directory);  //"/home/sftpuser/wurenjixiada"
            Iterator iterator = S.iterator();
            while (iterator.hasNext()){
                ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next();
                String name = file.getFilename();   //获取文件夹名称
                boolean flag = name.matches(rexp1);
                if(flag){
                    try {
                        DateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
                        Date start = dft.parse(name);   //文件夹日期
                        Long starTime=start.getTime();
                        Long endTime=currentTime.getTime();
                        Long num=endTime-starTime;  //时间戳相差的毫秒数
                        int between = (int) (num/24/60/60/1000);
                        if(between > numDay){
                            Vector<ChannelSftp.LsEntry> vector = sftp.ls(directory + "/" + name);
                            //判断超时文件夹下是否存在文件
                            if (vector.size() == 2) {   // 空文件夹,直接删除
                                sftp.rmdir(directory + "/" + name);
                            } else {
                                String fileName = "";
                                // 先删除文件夹下所有文件,再删除文件夹
                                for (ChannelSftp.LsEntry en : vector) {
                                    fileName = en.getFilename();
                                    if (".".equals(fileName) || "..".equals(fileName)) {
                                        continue;
                                    } else {
                                        sftp.rm(directory + "/" + name + "/" + fileName);
                                    }
                                }
                                // 删除文件夹
                                sftp.rmdir(directory + "/" + name);
                            }
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            String hostname = "121.41.24.39";
            int port = 22;
            String username = "sftpuser1";
            String password = "zxhc@1234";
            String workingPath = "/upload/wurenji/2222222";
            File file = new File("C:\\Users\\BraveSong\\Desktop\\当前工作内容\\20200803161338_PDYJ202012002_邱建锟.json");
            FTPUtil sftp = new FTPUtil(hostname,port,username,password);
            sftp.login();
            sftp.delOvertime("/upload/wurenji",7);
            sftp.logout();
        }
    
    }
    View Code

  • 外部调用该工具类时,首先需要传入连接的sftp服务器相关参数。sftp服务器的搭建可看此处https://www.cnblogs.com/BraveSong/p/15624671.htmlChannelSftp的使用心得

host为服务器地址ip,port为端口,userName为登录名,pwd为登陆密码。创建FTPUtil后使用login登录连接至服务器。https://www.cnblogs.com/BraveSong/p/15624671.html

连接之后,主要就upload()和delOvertime()中用的api进行相关说明。

以下所有方法使用中都需要注意的一点为,你连接sftp服务器的用户,登陆后默认所在的目录该用户是否有权限进行增删改查相关操作,以及该用户的根目录在何处,也会影响api的使用。

以sftpuser该用户为例,登陆后

ChannelSftp的使用心得

 

 

而使用root登录服务器可以发现该用户的根目录其实是在data下

ChannelSftp的使用心得

 

那么此时进行api操作的使用需要注意用绝对路径和相对路径,若用户没有相关权限,则会报no such file或deny拒绝这类的错误

 

sftp.ls()为展示连接用户目录下的所有文件。

sftp.rmdir()删除文件夹,若该文件夹中有文件是无法删除的,需要先进入其中将文件全部删掉,可以递归。

sftp.mkdir()创建文件夹。

sftp.cd()进入文件夹。

ChannelSftp的使用心得

 

上一篇:关于新版本oepnssh8.5rpm制作


下一篇:【REACT NATIVE 系列教程之七】统一ANDROID与IOS两个平台的程序入口&&区分平台的组件简介