Java SFTP 上傳、下載等操作
實際開發中用到了 SFTP
用於交換批量資料檔案,然後琢磨了下這方面的東西,基於 JSch
寫了個工具類記錄下,便於日後使用。
JSch
是 SSH2
的純Java實現。JSch
可以連線到sshd伺服器並使用埠轉發,X11轉發,檔案傳輸等,並且很方便的將其功能整合到Java程式中。
1、新增依賴
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
2、SFTPUtils 工具類
public class SFTPUtils {
private Logger log = LoggerFactory.getLogger(SFTPUtils.class);
private String host; // 主機名稱/IP
private int port = 22; // 埠
private String username; // 使用者名稱
private String password; // 密碼
private ChannelSftp sftp = null;
private Channel channel = null;
private Session session = null;
public SFTPUtils(String host, String userName, String password) {
this.host = host;
this.username = userName;
this.password = password;
}
public SFTPUtils(String host, int port, String userName, String password) {
this.host = host;
this.port = port;
this.username = userName;
this.password = password;
}
/**
* 連線SFTP伺服器
*
* @throws JSchException
*/
public void connect() throws JSchException {
JSch jSch = new JSch();
session = jSch.getSession(username, host, port);
session.setPassword(password);
session.setConfig(this.buildConfig());
session.connect();
channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
log.info("連線主機:{} 登入成功", host);
}
/**
* 構建連線配置引數
*
* @return Properties
*/
private Properties buildConfig() {
Properties properties = new Properties();
properties.put("StrictHostKeyChecking", "no");
return properties;
}
/**
* 關閉連線
*/
public void disconnect() {
try {
if (sftp.isConnected()) {
sftp.disconnect();
}
if (channel.isConnected()) {
channel.disconnect();
}
if (session.isConnected()) {
session.disconnect();
}
} catch (Throwable e) {
//ignore
}
}
/**
* 下載檔案
*
* @param sftpPath 伺服器路徑,不指定路徑預設是FTP的根路徑,指定路徑是指的SFTP的根路徑下開始。
* 例如:SFTP根路徑為:/sftp/file,那麼預設下載檔案會去根路徑下載,而指定 sftpPath 也是從根路徑下開始;
* 指定 sftpPath 為 word,那麼是從 /sftp/file/word 路徑中查詢檔案下載。為空表示忽略該引數。
* @param fileName 檔名
* @param toFilePath 下載儲存檔案路徑,路徑+檔名,例如:d:/test.txt
* @return
*/
public boolean downloadFile(String sftpPath, String fileName, String toFilePath) {
FileOutputStream fileOutputStream = null;
try {
if (StringUtils.isNotBlank(sftpPath)) {
sftp.cd(sftpPath);
}
fileOutputStream = new FileOutputStream(new File(toFilePath));
sftp.get(fileName, fileOutputStream);
return true;
} catch (Exception e) {
log.error("下載檔案錯誤", e);
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
//ignore
}
}
}
return false;
}
/**
* 上傳檔案
*
* @param sftpPath 伺服器路徑,不指定路徑預設是FTP的根路徑,指定路徑是指的SFTP的根路徑下開始。
* 例如:SFTP根路徑為:/sftp/file,那麼預設下載檔案會去根路徑下載,而指定 sftpPath 也是從根路徑下開始;
* 指定 sftpPath 為 word,那麼是從 /sftp/file/word 路徑中查詢檔案下載。為空表示忽略該引數。
* @param fileName 上傳後檔名
* @param localFilePath 檔案路徑,路徑+檔名,例如:d:/test.txt
* @return
*/
public boolean uploadFile(String sftpPath, String fileName, String localFilePath) {
FileInputStream inputStream = null;
try {
if (StringUtils.isNotBlank(sftpPath)) {
sftp.cd(sftpPath);
}
inputStream = new FileInputStream(new File(localFilePath));
sftp.put(inputStream, fileName);
return true;
} catch (Exception e) {
log.error("上傳檔案錯誤", e);
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
//ignore
}
}
}
return false;
}
/**
* 上傳檔案
*
* @param sftpPath 伺服器路徑,不指定路徑預設是FTP的根路徑,指定路徑是指的SFTP的根路徑下開始。
* 例如:SFTP根路徑為:/sftp/file,那麼預設下載檔案會去根路徑下載,而指定 sftpPath 也是從根路徑下開始;
* 指定 sftpPath 為 word,那麼是從 /sftp/file/word 路徑中查詢檔案下載。為空表示忽略該引數。
* @param fileName 上傳後檔名
* @param inputStream 檔案輸入流
* @return
*/
public boolean uploadFile(String sftpPath, String fileName, InputStream inputStream) {
try {
if (StringUtils.isNotBlank(sftpPath)) {
sftp.cd(sftpPath);
}
sftp.put(inputStream, fileName);
return true;
} catch (Exception e) {
log.error("上傳檔案錯誤", e);
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
//ignore
}
}
}
return false;
}
/**
* 刪除檔案
*
* @param sftpPath 伺服器路徑,不指定路徑預設是FTP的根路徑,指定路徑是指的SFTP的根路徑下開始。
* 例如:SFTP根路徑為:/sftp/file,那麼預設下載檔案會去根路徑下載,而指定 sftpPath 也是從根路徑下開始;
* 指定 sftpPath 為 word,那麼是從 /sftp/file/word 路徑中查詢檔案下載。為空表示忽略該引數。
* @param fileName 檔名
* @return
*/
public boolean deleteFile(String sftpPath, String fileName) {
try {
if (StringUtils.isNotBlank(sftpPath)) {
sftp.cd(sftpPath);
}
sftp.rm(fileName);
return true;
} catch (Exception e) {
log.error("刪除檔案失敗", e);
}
return false;
}
/**
* 查詢指定目錄下資訊
*
* @param sftpPath 伺服器路徑,不指定路徑預設是FTP的根路徑,指定路徑是指的SFTP的根路徑下開始。
* 例如:SFTP根路徑為:/sftp/file,那麼預設下載檔案會去根路徑下載,而指定 sftpPath 也是從根路徑下開始;
* 指定 sftpPath 為 word,那麼是從 /sftp/file/word 路徑中查詢檔案下載。為空表示忽略該引數。
* @return
*/
public List<String> listFiles(String sftpPath) throws SftpException {
Vector files = sftp.ls(sftpPath);
List<String> result = new ArrayList<String>();
Iterator iterator = files.iterator();
while (iterator.hasNext()) {
LsEntry isEntity = (LsEntry) iterator.next();
result.add(isEntity.getFilename());
}
return result;
}
}
在使用的的時候,需要呼叫 connect()
開啟連線,使用完後呼叫 disconnect()
關閉連線 。
jsch
官方的文件說明 http://www.jcraft.com/jsch/
本文主要用於個人記錄筆記!