SFTP使用资料整理及例子

SFTP

简介

SFTP是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。SFTP 为 SSH的一部份,是一种传输文件到服务器的安全方式。SFTP是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。

使用介绍

JSch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到你自己的应用程序。
本文只介绍如何使用JSch实现的SFTP功能。

使用JSch需要添加下面的依赖包

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.51</version>
</dependency>
ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:

put(): 文件上传
get(): 文件下载
cd(): 进入指定目录
ls(): 得到指定目录下的文件列表
rename(): 重命名指定文件或目录
rm(): 删除指定文件
mkdir(): 创建目录
rmdir(): 删除目录

JSch支持三种文件传输模式:
OVERWRITE

完全覆盖模式,这是JSch的默认文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。

RESUME

恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,则会从上一次中断的地方续传。

APPEND

追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。

文件上传例子:

常量类
package test.test;

/**
 * 常量类
 *
 * @author duxiao
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class SFTPConstants {

    public static final String SFTP_REQ_HOST = "host";
    public static final String SFTP_REQ_PORT = "port";
    public static final String SFTP_REQ_USERNAME = "username";
    public static final String SFTP_REQ_PASSWORD = "password";
    public static final int SFTP_DEFAULT_PORT = 22;
    public static final String SFTP_REQ_LOC = "location";

}
创建ChannelSftp对象
package test.test;

import java.util.Map;
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;

/**
 * 
 * SFTP通道对象<br>
 * 在应用程序中就可以使用该对象来调用SFTP的各种操作方法。<br>
 * 比如put(),get()等
 * 
 * @author duxiao
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class SFTPChannel {
    Session session = null;
    Channel channel = null;

    public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException {

        String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);
        String port = sftpDetails.get(SFTPConstants.SFTP_REQ_PORT);
        String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);
        String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);

        int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT;
        if (port != null && !port.equals("")) {
            ftpPort = Integer.valueOf(port);
        }

        // 创建JSch对象
        JSch jsch = new JSch();

        // 根据用户名,主机ip,端口获取一个Session对象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
        System.out.println("Session created.");
        if (ftpPassword != null) {
            // 设置密码
            session.setPassword(ftpPassword);
        }
        Properties config = new Properties();
        // 首次登陆远程的时候提示Are you sure you want to continue connecting (yes/no)。这时用sshpass会不好使。
        config.put("StrictHostKeyChecking", "no");
        // 为Session对象设置properties
        session.setConfig(config);
        // 设置timeout时间
        session.setTimeout(timeout);
        // 通过Session建立链接
        session.connect();
        System.out.println("Session connected.");
        System.out.println("Opening Channel.");

        // 打开SFTP通道
        channel = session.openChannel("sftp");

        // 建立SFTP通道的连接
        channel.connect();
        System.out.println("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName
                + ", returning: " + channel);
        return (ChannelSftp) channel;
    }

    public void closeChannel() throws Exception {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }
}
应用测试类
package test.test;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import com.jcraft.jsch.ChannelSftp;

/**
 * 
 * 功能测试类
 * 
 * @author duxiao
 * @see [相关类/方法](可选)
 * @since [产品/模块版本] (可选)
 */
public class SFTPTest {

    public SFTPChannel getSFTPChannel() {
        return new SFTPChannel();
    }

    public static void main(String[] args) throws Exception {
        SFTPTest test = new SFTPTest();

        Map<String, String> sftpDetails = new HashMap<String, String>();
        // 设置主机ip,端口,用户名,密码
        sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "172.16.128.165");
        sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, "product");
        sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, "U13QGqODA");
        sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, "22");

        // 本地文件名
        String src = "F:\\ueditor1_4_3-utf8-jsp.zip";

        // 目标文件名
        String dst = "/home/product/response/ueditor1_4_3-utf8-jsp.zip";

        SFTPChannel channel = test.getSFTPChannel();
        ChannelSftp chSftp = channel.getChannel(sftpDetails, 60000);

        // 代码段1
        // 使用OVERWRITE模式
        OutputStream out = chSftp.put(dst, ChannelSftp.OVERWRITE);
        // 设定每次传输的数据块大小为256KB
        byte[] buff = new byte[1024 * 256];
        int read;
        if (out != null) {
            System.out.println("Start to read input stream");
            InputStream is = new FileInputStream(src);
            do {
                read = is.read(buff, 0, buff.length);
                if (read > 0) {
                    out.write(buff, 0, read);
                }
                out.flush();
            } while (read >= 0);
            System.out.println("input stream read done.");
        }

        // 代码段2
        // chSftp.put(src, dst, ChannelSftp.OVERWRITE);

        // 代码段3
        // chSftp.put(new FileInputStream(src), dst, ChannelSftp.OVERWRITE);

        chSftp.quit();
        channel.closeChannel();
    }
}

其中测试类中的代码段1,2,3可以分别执行,体现了3中不同的上传方式,结果都是一致。
小伙伴们只要把这三个类考出去运行一下,java实现SFTP的各种功能就很容易理解了。

碰到问题

以前联通给我们消费记录需求需要该技术使用。后来需求改动。已经没有改技术的使用了。没有碰到问题。

评价

JSch是SSH2功能JAVA实现最常用的最好用的工具。

参考资料

百度文库的资料

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值