使用jsch实现sftp上传下载

本文介绍了一种使用Java实现的SFTP文件传输服务,包括文件的上传和下载功能。通过JSch库操作SFTP通道,实现了远程文件的高效传输,并详细展示了如何创建远程目录和处理文件路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.csii.loan.transfer.sftp;

import com.csii.loan.transfer.FileTransferService;
import com.jcraft.jsch.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Arrays;
import java.util.Properties;

/**
 * @author xulong
 */
public class SftpFileTransferServiceImpl implements FileTransferService {

    private SftpConfig sftpConfig;

    /**
     * 通道类型
     */
    private static final String CHANNEL_TYPE = "sftp";

    private static final Logger logger = LoggerFactory.getLogger(SftpFileTransferServiceImpl.class);

    /**
     * 下载远程文件
     *
     * @param remoteFilePath 远程文件路径
     * @param localDirPath   本地文件目录
     * @throws JSchException
     * @throws SftpException
     */
    @Override
    public void download(String remoteFilePath, String localDirPath) throws Exception {
        File localDirFile = new File(localDirPath);
        // 判断本地目录是否存在,不存在需要新建各级目录
        if (!localDirFile.exists()) {
            localDirFile.mkdirs();
        }
        ChannelSftp sftpChannel = getSftpChannel();
        if (logger.isInfoEnabled()) {
            logger.info("开始获取远程文件:[{}]---->[{}]", new Object[]{remoteFilePath, localDirPath});
        }
        sftpChannel.get(remoteFilePath, localDirPath);
        if (logger.isInfoEnabled()) {
            logger.info("文件下载成功");
        }
        disconnect(sftpChannel);
    }

    /**
     * 获取sftp
     * @author 虫子哥
     * @return
     * @throws JSchException
     * @throws SftpException
     */
    private ChannelSftp getSftpChannel() throws JSchException, SftpException {
        JSch jsch = new JSch();
        Session session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getHostname(), sftpConfig.getPort());
        session.setPassword(sftpConfig.getPassword());
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.setTimeout(sftpConfig.getTimeout());
        session.connect();
        ChannelSftp sftpChannel = (ChannelSftp) session.openChannel(CHANNEL_TYPE);
        sftpChannel.connect();
        return sftpChannel;
    }

    private void disconnect(ChannelSftp sftpChannel) throws JSchException {
        sftpChannel.disconnect();
        sftpChannel.getSession().disconnect();
    }

    /**
     * 文件上传
     *
     * @param localFilePath 本地文件路径
     * @param remoteDirPath 远程目录路径
     * @throws JSchException
     * @throws SftpException
     */
    @Override
    public void upload(String localFilePath, String remoteDirPath) throws Exception {
        ChannelSftp sftpChannel = getSftpChannel();
        // 需要新建远程目录
        mkRemoteDir(remoteDirPath, sftpChannel);
        if (logger.isInfoEnabled()) {
            logger.info("开始上传文件:[{}]---->[{}]", new Object[]{localFilePath, remoteDirPath});
        }
        sftpChannel.mkdir(remoteDirPath);
        sftpChannel.put(localFilePath, remoteDirPath, ChannelSftp.OVERWRITE);
        if (logger.isInfoEnabled()) {
            logger.info("文件上传成功");
        }
        disconnect(sftpChannel);
    }

    /**
     * 创建远程目录
     *
     * @param path
     * @param sftp
     * @throws SftpException
     * @author xulong
     */
    private void mkRemoteDir(String path, ChannelSftp sftp) throws SftpException {
        String[] folders = path.split("/");
        // 找到已经存在的目录对应的数组下标
        int existDirIndex = getRemoteDirExistIndex(folders, sftp);
        int dirLength = folders.length;
        for (int i = existDirIndex + 1; i < dirLength; i++) {
            String[] dirClone = Arrays.copyOfRange(folders, 0, i + 1);
            String currentPath = StringUtils.join(dirClone, '/');
            sftp.mkdir(currentPath);
        }
    }

    /**
     * 判断当前存在的目录
     *
     * @param folders
     * @param sftp
     * @return
     * @author xulong
     */
    private int getRemoteDirExistIndex(String[] folders, ChannelSftp sftp) {
        int length = folders.length;
        for (int i = 0; i < length; i++) {
            // 目录从后往前开始检查是否存在
            String[] cloneFolderArray = Arrays.copyOfRange(folders, 0, (length - i));
            String currentPath = StringUtils.join(cloneFolderArray, '/');
            try {
                sftp.cd(currentPath);
                // 返回当前已经存在目录的数组下标
                return (length - i - 1);
            } catch (SftpException e) {
                System.out.println(String.format("远程目录[%s]不存在", currentPath));
                continue;
            }
        }
        return 0;
    }

    public void setSftpConfig(SftpConfig sftpConfig) {
        this.sftpConfig = sftpConfig;
    }
}
package com.csii.loan.transfer.sftp;

import org.springframework.core.io.Resource;

/**
 * @author xulong
 */
public class SftpConfig {

    private String hostname;
    private Integer port;
    private String username;
    private String password;
    private Integer timeout;
    private Resource privateKey;
    private String remoteRootPath;
    private String fileSuffix;

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public Integer getPort() {
        return port;
    }

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

    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 Integer getTimeout() {
        return timeout;
    }

    public void setTimeout(Integer timeout) {
        this.timeout = timeout;
    }

    public Resource getPrivateKey() {
        return privateKey;
    }

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

    public String getRemoteRootPath() {
        return remoteRootPath;
    }

    public void setRemoteRootPath(String remoteRootPath) {
        this.remoteRootPath = remoteRootPath;
    }

    public String getFileSuffix() {
        return fileSuffix;
    }

    public void setFileSuffix(String fileSuffix) {
        this.fileSuffix = fileSuffix;
    }
}

 

转载于:https://my.oschina.net/xulong1/blog/1612382

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值