以下为个人使用过程中的心得经验
- ChannelSftp是Java连接sftp服务器并进行相关操作的核心类,有许多api方法可以使用,以下就本人相关代码进行说明。
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.html
host为服务器地址ip,port为端口,userName为登录名,pwd为登陆密码。创建FTPUtil后使用login登录连接至服务器。https://www.cnblogs.com/BraveSong/p/15624671.html
连接之后,主要就upload()和delOvertime()中用的api进行相关说明。
以下所有方法使用中都需要注意的一点为,你连接sftp服务器的用户,登陆后默认所在的目录该用户是否有权限进行增删改查相关操作,以及该用户的根目录在何处,也会影响api的使用。
以sftpuser该用户为例,登陆后
而使用root登录服务器可以发现该用户的根目录其实是在data下
那么此时进行api操作的使用需要注意用绝对路径和相对路径,若用户没有相关权限,则会报no such file或deny拒绝这类的错误
sftp.ls()为展示连接用户目录下的所有文件。
sftp.rmdir()删除文件夹,若该文件夹中有文件是无法删除的,需要先进入其中将文件全部删掉,可以递归。
sftp.mkdir()创建文件夹。
sftp.cd()进入文件夹。