java常用的sftp 工具包

1、jsch 挺老的工具包 jdk可以最低支持到1.6 目前最高版本0.1.55 已经多年没有更新,jsch功能其实挺强大的,只不过时间的原因,java7后的新写法 jsch都不支持 ,如果自己封装一下 也是挺好用的,毕竟他支持文件和文件流上传 

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

/**
 * SFTP连接工具。
 * @author wanglei
 * @version 1.0
 */
public class SFtpTool implements AutoCloseable {

    private static final int TIME_OUT = 60000;

    private Session sshSession;

    private ChannelSftp sftp;

    SFtpTool(final String host, final int port, final String username, final String password) {
        connect(host, port, username, password);
    }

    /**
     * 连接SFTP服务器。
     * @param host 服务器ip
     * @param port 端口
     * @param username 鉴权用户名
     * @param password 密码
     */
    private void connect(final String host, final int port, final String username, final String password) {

        try {
            final JSch jsch = new JSch();
            sshSession = jsch.getSession(username, host, port);
            sshSession.setTimeout(TIME_OUT);
            sshSession.setPassword(password);
            final Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            final Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
        } catch (final JSchException e) {

            throw new BusinessException(String.format("连接到远程SFTP服务器失败,主机名是:%s", host), e);
        }
    }

    /**
     * 上传文件。
     *
     * @param directory 文件要上传的目录。
     * @param file 要上传的文件
     */
    public void upload(final String directory, final File file) {

        //文件名称
        final String fileName = file.getName();

        try (final FileInputStream io = new FileInputStream(file)) {
            sftp.cd(directory);
            sftp.put(io, fileName);
        } catch (final SftpException e) {

            throw new BusinessException(String.format("SFTP连接异常,文件目录是:%s", directory), e);
        } catch (final IOException e) {

            throw new BusinessException(String.format("文件写读异常,文件名是:%s", fileName), e);
        }
    }

    @Override
    public void close() {
        if (sftp != null) {
            sftp.disconnect();
        }
        if (sshSession != null) {
            sshSession.disconnect();
        }
    }

    public static SFtpToolBuilder builder() {
        return new SFtpToolBuilder();
    }

    /**
     * SFtpToolBuilder.
     */
    public static class SFtpToolBuilder {
        private String username;

        private String password;

        private int port;

        private String host;

        /**
         * 设置sftp用户名。
         * @param username 鉴权用户名
         * @return SFtpToolBuilder
         */
        public SFtpToolBuilder username(final String username) {
            this.username = username;
            return this;
        }

        /**
         * 设置sftp密码。
         * @param password 鉴权密码
         * @return SFtpToolBuilder
         */
        public SFtpToolBuilder password(final String password) {
            this.password = password;
            return this;
        }

        /**
         * 设置服务器IP。
         * @param host 服务器IP
         * @return SFtpToolBuilder
         */
        public SFtpToolBuilder host(final String host) {
            this.host = host;
            return this;
        }

        /**
         * 设置sftp端口。
         * @param port 端口
         * @return SFtpToolBuilder
         */
        public SFtpToolBuilder port(final int port) {
            this.port = port;
            return this;
        }

        /**
         * 构造 SFtpTool。
         * @return SFtpTool
         */
        public SFtpTool build() {
            return new SFtpTool(this.host, this.port, this.username, this.password);
        }
    }
}

实际使用

try (final SFtpTool sFtpTool = 
    SFtpTool.builder().username("x").password("x").host("x").port(x).build()) {
    sFtpTool.upload("remote", file); 
}

2、ssh-j新秀工具包 最低支持java8 搭配try-with-resource 代码量很少 不支持文件流上传,原因嘛 实际的上传方法进行了一系列的判断 是不是文件 、是不是文件夹 我觉得暂时不支持 ,以后应该会支持的,只不过要改动一下底层的逻辑

原生使用也是很方便的

    try (final SSHClient sshClient = new SSHClient()) {
        sshClient.addHostKeyVerifier(new PromiscuousVerifier());
        sshClient.connect("192.168.31.202", 22);
        sshClient.authPassword("root", "root");
        try (final SFTPClient sftpClient = sshClient.newSFTPClient()) {
            sftpClient.ls("/home/root/").forEach(System.out::println);
        }
    }

那我们如果想业务分离就需要封装一下(样例,不做NPE等判断)

import java.io.IOException;

import org.apache.commons.io.IOUtils;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;

/**
 * sftpClient 工具类。
 * @author wanglei
 * @version 1.0
 */
public class SSHJSFtpClient implements AutoCloseable {

    private SSHClient sshClient = null;

    private SFTPClient sftpClient = null;

    public SSHJSFtpClient(String host, int port, String username, String password) throws IOException {
        sshClient = new SSHClient();
        sshClient.addHostKeyVerifier(new PromiscuousVerifier());
        sshClient.connect(host, port);
        sshClient.authPassword(username, password);
    }

    public SFTPClient getSftpClient() throws IOException {
        if (sftpClient != null) {
            return sftpClient;
        }
        sftpClient = sshClient.newSFTPClient();
        return sftpClient;
    }


    @Override
    public void close() throws Exception {
        IOUtils.close(sftpClient, sshClient);
    }

}

实际调用

try (final SSHJSFtpClient sftpClient = new SSHJSFtpClient("192.168.31.202", 22, "root", "root")) 
{

    sftpClient.getSftpClient().ls("/home/root/").forEach(System.out::println);
}

3、apache的commons VFS 底层也是jsch 不讨论了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值