JAVA 程序 jsch实现对SFTP服务器的操作

freeSSHd搭建

windows 上搭建 sftp 服务器 --freesshd

下载 jsch.jar

JAVA程序实现对SFTP服务器的操作

Java实现的SFTP(文件上传详解篇)

JAVA SFTP文件上传、下载及批量下载

1. 配置类

package com.test.sftp;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * Created by luxian.zhang on 2021/5/10.
 */
@Configuration
public class SftpConfig {
    public final static String SEPERATOR = "/";

    @Value("${sftp.host:}")
    private String host;//sftp服务器ip

    @Value("${sftp.username:}")
    private String username;//用户名

    @Value("${sftp.password:}")
    private String password;//密码

    @Value("${sftp.private.key:}")
    private String privateKey;//密钥文件路径

    @Value("${sftp.passphrase:}")
    private String passphrase;//密钥口令

    @Value("${sftp.port:}")
    private Integer port;//默认的sftp端口号是22

    @Value("${sftp.program.dir:}")
    private String programDir;//程式根目录, 默认/

    public static String HOST;
    public static String USERNAME;
    public static String PASSWORD;
    public static String PRIVATE_KEY;
    public static String PASSPHRASE;
    public static Integer PORT;
    public static String PROGRAM_DIR;

    @PostConstruct
    public void init() {
        HOST = host;
        USERNAME = username;
        PASSWORD = password;
        PRIVATE_KEY = privateKey;
        PASSPHRASE = passphrase;
        if(port == null){
            port = 22;
        }
        PORT = port;
        PROGRAM_DIR = programDir;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

    public String getPrivateKey() {
        return privateKey;
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

    public String getPassphrase() {
        return passphrase;
    }

    public void setPassphrase(String passphrase) {
        this.passphrase = passphrase;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getProgramDir() {
        return programDir;
    }

    public void setProgramDir(String programDir) {
        this.programDir = programDir;
    }
}

2. 操作类和调试 

package com.test.sftp;

import com.alibaba.fastjson.JSON;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.test.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

/**
 * Created by luxian.zhang on 2021/5/10.
 */
public class SftpConn {
    private static Logger _log = LoggerFactory.getLogger(SftpConn.class);
    private ChannelSftp sftp = null;
    private Session session = null;
    private String rootDir;

    public SftpConn() throws Exception{
        if(StringUtil.isNullOrEmpty(SftpConfig.HOST)){
            throw new RuntimeException("sftp配置不全 【 sftp.host, sftp.username, sftp.password 】");
        }
        getSftpChannel(SftpConfig.HOST, SftpConfig.USERNAME, SftpConfig.PASSWORD, SftpConfig.PRIVATE_KEY, SftpConfig.PASSPHRASE, SftpConfig.PORT, SftpConfig.PROGRAM_DIR);
    }

    public SftpConn(String host, String username, String password, String privateKey, String passphrase, Integer port, String rootDir) throws Exception{
        getSftpChannel(host, username, password, privateKey, passphrase, port, rootDir);
    }

    private void getSftpChannel(String host, String username, String password, String privateKey, String passphrase, Integer port, String rootDir) throws Exception{
        if(port == null){
            port = 22;
        }
        if(StringUtil.isNullOrEmpty(host)){
            return;
        }

        try {
            JSch jsch = new JSch();
            if (privateKey != null && !"".equals(privateKey)) {
                //使用密钥验证方式,密钥可以使有口令的密钥,也可以是没有口令的密钥
                if (passphrase != null && "".equals(passphrase)) {
                    jsch.addIdentity(privateKey, passphrase);
                } else {
                    jsch.addIdentity(privateKey);
                }
            }
            session = jsch.getSession(username, host, port);
            if (password != null && !"".equals(password)) {
                session.setPassword(password);
            }
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");// do not verify host key
            session.setConfig(sshConfig);
            // session.setTimeout(timeout);
            session.setServerAliveCountMax(40);
            session.setServerAliveInterval(92000);
            session.connect();

            //参数sftp指明要打开的连接是sftp连接
            sftp =  (ChannelSftp)session.openChannel("sftp");
            sftp.connect();
            if(rootDir == null){
                rootDir = "";
            }
            this.rootDir = rootDir;
        } catch (Exception e) {
            SftpConn.disconnect(this);
            throw e;
        }
    }

    /**
     * 上传文件并且清理目录
     * @param directory
     * @param uploadFileList
     * @throws Exception
     */
    public void cleanAndUplaod(String directory, List<String> uploadFileList) throws Exception{
        if(StringUtil.isNullOrEmpty(directory)){
            throw new RuntimeException("参数错误,上传的目标目录为空");
        }
        this.upload(directory, uploadFileList, true);
    }

    /**
     * 上传文件并且清理目录
     * @param srcDir
     * @param directory 相对sftp根目录
     * @throws Exception
     */
    public void cleanAndUplaod(String srcDir, String directory) throws Exception{
        if(StringUtil.isNullOrEmpty(srcDir) || StringUtil.isNullOrEmpty(directory)){
            return;
        }
        File srcDirFile = new File(srcDir);
        List<String> uploadFileList = new ArrayList<>();
        if(!srcDirFile.exists()){
           return;
        }
        File[] files = srcDirFile.listFiles();
        for (File file : files) {
            uploadFileList.add(file.getAbsolutePath());
        }
        this.upload(directory, uploadFileList, true);
    }

    /**
     * 创建目录
     * @param createpath
     * @return
     */
    public boolean createDir(String createpath) throws Exception{
        if (isDirExist(createpath)){
            return true;
        }
        String pathArry[] = createpath.split(SftpConfig.SEPERATOR);
        StringBuffer filePath = new StringBuffer(SftpConfig.SEPERATOR);
        for (String path : pathArry){
            if (path.equals("")){
                continue;
            }
            filePath.append(path + SftpConfig.SEPERATOR);
            if (isDirExist(filePath.toString())){
                sftp.cd(filePath.toString());
            } else{
                // 建立目录
                sftp.mkdir(filePath.toString());
            }

        }
        return true;
    }

    /**
     * 上传文件
     * @param directory 目标目录绝对路径
     * @param uploadFileList  上传的文件路径
     * @param clearDir  是否需要清理目录
     * @throws Exception
     */
    public void upload(String directory, List<String> uploadFileList, boolean clearDir) throws Exception {
        if(CollectionUtils.isEmpty(uploadFileList)){
            return;
        }
        if(StringUtil.isNullOrEmpty(directory)){
            directory = SftpConfig.SEPERATOR;
        }
        _log.info("===== SFTP 上传文件开始 {} to {} ", JSON.toJSONString(uploadFileList), directory);
        long start = System.currentTimeMillis();
        //不是根目录
        if(!directory.equals(SftpConfig.SEPERATOR)){
            //创建目录
            boolean exist = isDirExist(directory);
            if(!exist){
                //不存在就创建
                createDir(directory);
            }
            if(exist && clearDir){
                //如果存在那么需要清空目录里面的文件
                Vector<ChannelSftp.LsEntry> vector = sftp.ls(directory);
                int size = vector.size();
                for (int i = 0; i < size; i++) {
                    ChannelSftp.LsEntry file = vector.get(i);
                    String fileName = file.getFilename();
                    this.deleteFile(directory, fileName);
                }
            }
        }
        sftp.cd(directory);
        for (String filePath : uploadFileList) {
            File file = new File(filePath);
            sftp.put(new FileInputStream(file), file.getName());
        }

        _log.info("===== SFTP 上传文件成功  to {}  spends {} ms", directory, System.currentTimeMillis() - start);
    }

    /**
     * 判断目录是否存在
     * @param directory
     * @return
     */
    public boolean isDirExist(String directory){
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e){
            if (e.getMessage().toLowerCase().equals("no such file")){
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }

    /**
     * 删除stfp文件
     * @param directory:要删除文件所在目录
     * @param deleteFile:要删除的文件
     */
    public void deleteFile(String directory, String deleteFile) throws Exception{
        if(deleteFile.equals(".") || deleteFile.equals("..")){
            return;
        }
        sftp.rm(directory + SftpConfig.SEPERATOR + deleteFile);
    }

    /**
     * 关闭连接
     */
    public static void disconnect(SftpConn sftpConn){
        if(sftpConn == null){
            return;
        }
        ChannelSftp sftp = sftpConn.getSftp();
        Session session = sftpConn.getSession();
        if (sftp != null && sftp.isConnected()){
            sftp.disconnect();
        }
        if (session != null && session.isConnected()){
            session.disconnect();
        }
    }

    public ChannelSftp getSftp() {
        return sftp;
    }

    public void setSftp(ChannelSftp sftp) {
        this.sftp = sftp;
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public static void main(String[] args) {
        String host = "192.168.1.103";
        String username = "test";
        String password = "110110";
        List<String> uploadFileList = new ArrayList<>();
        uploadFileList.add("D:\\machine\\CNC01\\3F01.NC");
        uploadFileList.add("D:\\machine\\CNC01\\4F02.J00");

        SftpConn sftp = null;
        try {
            String rootDir = SftpConfig.SEPERATOR + "machine";
            sftp = new SftpConn(host, username, password, null, null, null, rootDir);
            sftp.cleanAndUplaod(rootDir + SftpConfig.SEPERATOR + "CNC02", uploadFileList);
        } catch (Exception e) {
            _log.error("上传文件出错", e);
        } finally {
            SftpConn.disconnect(sftp);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值