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