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/
本文主要用於個人記錄筆記!