天天看點

Jsch - Java實作的SFTP檔案上傳

Jsch表示Java Secure Channel。SFTP是Secure File Transfer Protocol的縮寫,安全檔案傳送協定。可以為傳輸檔案提供一種安全的加密方法。SFTP 為 SSH的一部份,是一種傳輸檔案到伺服器的安全方式。SFTP是使用加密傳輸認證資訊和傳輸的資料,是以,使用SFTP是非常安全的。但是,由于這種傳輸方式使用了加密/解密技術,是以傳輸效率比普通的FTP要低得多,如果您對網絡安全性要求更高時,可以使用SFTP代替FTP。

jar包:

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
		<dependency>
		    <groupId>com.jcraft</groupId>
		    <artifactId>jsch</artifactId>
		    <version>0.1.54</version>
		</dependency>
           

 ChannelSftp類:

ChannelSftp類是JSch實作SFTP核心類,它包含了所有SFTP的方法,如:

put():      檔案上傳

get():      檔案下載下傳

cd():       進入指定目錄

ls():       得到指定目錄下的檔案清單

rename():   重命名指定檔案或目錄

rm():       删除指定檔案

mkdir():    建立目錄

rmdir():    删除目錄

JSch支援三種檔案傳輸模式:

OVERWRITE 完全覆寫模式,這是JSch的預設檔案傳輸模式,即如果目标檔案已經存在,傳輸的檔案将完全覆寫目标檔案,産生新的檔案。
RESUME

恢複模式,如果檔案已經傳輸一部分,這時由于網絡或其他任何原因導緻檔案傳輸中斷,如果下一次傳輸相同的檔案,

則會從上一次中斷的地方續傳。

APPEND 追加模式,如果目标檔案已存在,傳輸的檔案将在目标檔案後追加。

實作檔案上傳可以調用ChannelSftp對象的put方法。ChannelSftp中有12個put方法的重載方法:

public void put(String src, String dst)

将本地檔案名為src的檔案上傳到目标伺服器,目标檔案名為dst,若dst為目錄,則目标檔案名将與src檔案名相同。

采用預設的傳輸模式:OVERWRITE

public void put(String src, String dst, int mode)

将本地檔案名為src的檔案上傳到目标伺服器,目标檔案名為dst,若dst為目錄,則目标檔案名将與src檔案名相同。

指定檔案傳輸模式為mode(mode可選值為:ChannelSftp.OVERWRITE,ChannelSftp.RESUME,

ChannelSftp.APPEND)

public void put(String src, String dst, SftpProgressMonitor monitor)

将本地檔案名為src的檔案上傳到目标伺服器,目标檔案名為dst,若dst為目錄,則目标檔案名将與src檔案名相同。

采用預設的傳輸模式:OVERWRITE

并使用實作了SftpProgressMonitor接口的monitor對象來監控檔案傳輸的進度。

public void put(String src, String dst,

SftpProgressMonitor monitor, int mode)

将本地檔案名為src的檔案上傳到目标伺服器,目标檔案名為dst,若dst為目錄,則目标檔案名将與src檔案名相同。

指定傳輸模式為mode

并使用實作了SftpProgressMonitor接口的monitor對象來監控檔案傳輸的進度。

public void put(InputStream src, String dst)

将本地的input stream對象src上傳到目标伺服器,目标檔案名為dst,dst不能為目錄。

采用預設的傳輸模式:OVERWRITE

public void put(InputStream src, String dst, int mode)

将本地的input stream對象src上傳到目标伺服器,目标檔案名為dst,dst不能為目錄。

指定檔案傳輸模式為mode

public void put(InputStream src, String dst, SftpProgressMonitor monitor)

将本地的input stream對象src上傳到目标伺服器,目标檔案名為dst,dst不能為目錄。

采用預設的傳輸模式:OVERWRITE

并使用實作了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public void put(InputStream src, String dst,

SftpProgressMonitor monitor, int mode)

将本地的input stream對象src上傳到目标伺服器,目标檔案名為dst,dst不能為目錄。

指定檔案傳輸模式為mode

并使用實作了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public OutputStream put(String dst)

該方法傳回一個輸出流,可以向該輸出流中寫入資料,最終将資料傳輸到目标伺服器,目标檔案名為dst,dst不能為目錄。

采用預設的傳輸模式:OVERWRITE

public OutputStream put(String dst, final int mode)

該方法傳回一個輸出流,可以向該輸出流中寫入資料,最終将資料傳輸到目标伺服器,目标檔案名為dst,dst不能為目錄。

指定檔案傳輸模式為mode

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode) 

該方法傳回一個輸出流,可以向該輸出流中寫入資料,最終将資料傳輸到目标伺服器,目标檔案名為dst,dst不能為目錄。

指定檔案傳輸模式為mode

并使用實作了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset)

該方法傳回一個輸出流,可以向該輸出流中寫入資料,最終将資料傳輸到目标伺服器,目标檔案名為dst,dst不能為目錄。

指定檔案傳輸模式為mode

并使用實作了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

offset指定了一個偏移量,從輸出流偏移offset開始寫入資料。

建立ChannelSftp對象:

編寫一個工具類,傳入ip,使用者名及密碼得到一個SFTP channel對象,即ChannelSftp的執行個體對象,在應用程式中就可以使用該對象來調用SFTP的各種操作方法。

SFTPChannel.java

import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

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;

public class SFTPChannel {
    Session session = null;
    Channel channel = null;

    private static final Logger LOG = Logger.getLogger(SFTPChannel.class.getName());

    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 = new JSch(); // 建立JSch對象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort); // 根據使用者名,主機ip,端口擷取一個Session對象
        LOG.debug("Session created.");
        if (ftpPassword != null) {
            session.setPassword(ftpPassword); // 設定密碼
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config); // 為Session對象設定properties
        session.setTimeout(timeout); // 設定timeout時間
        session.connect(); // 通過Session建立連結
        LOG.debug("Session connected.");

        LOG.debug("Opening Channel.");
        channel = session.openChannel("sftp"); // 打開SFTP通道
        channel.connect(); // 建立SFTP通道的連接配接
        LOG.debug("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();
        }
    }
}
           

SFTPConstants:

SFTPConstans.java

package com.longyg.sftp;

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";
}
           

簡單執行個體方法:

public void putResource(String firmwarePath,String name, byte[] data) {
        SFTPChannel channel = new SFTPChannel();
        Map<String, String> sftpDetails = new HashMap<String, String>();
        // 設定主機ip,端口,使用者名,密碼
        sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, sshHostS);
        sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, sshNameD);
        sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, sshPassD);
        sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, sshPortD);
        ChannelSftp chSftp = null;
        try {
			chSftp = channel.getChannel(sftpDetails, 60000);
			chSftp.put(firmwarePath+name, firmwarePath+name, ChannelSftp.OVERWRITE);
		} catch (JSchException e) {
			logger.info("JSchException JSchException:" + e);
		} catch (Exception e) {
			logger.info("Exception Exception:" + e);
		}finally {
			chSftp.quit();
			try {
				channel.closeChannel();
			} catch (Exception e) {
			}
		}
    }
           

Jsch支援在檔案傳輸時對傳輸進度的監控。可以實作JSch提供的SftpProgressMonitor接口來完成這個功能。由于業務不需要,此處省略,繼續學習可以參考原文章。

 原文章參考:http://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html