sftp作為臨時的文件存儲位置,在某些場合還是有其應景的,比如對賬文件存放。需要提供一個上傳的工具類。實現方法參考下:
pom.xml中引入類庫:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
sftp工具類和使用命令行是一樣的操作方法,上傳下載如下:
public class SftpUploadTest { private ChannelSftp sftp = null; private Session sshSession = null; private String username; private String password; private String host; private int port; public SftpUploadTest(String username, String password, String host, int port) { this.username = username; this.password = password; this.host = host; this.port = port; } /** * 連接sftp服務器 * * @return ChannelSftp sftp連接實例 */ public ChannelSftp connect() { info("-->sftp連接開始>>>>>> " + host + ":" + port + " >>>username=" + username); JSch jsch = new JSch(); try { jsch.getSession(username, host, port); sshSession = jsch.getSession(username, host, port); sshSession.setPassword(password); Properties properties = new Properties(); properties.put("StrictHostKeyChecking", "no"); sshSession.setConfig(properties); sshSession.connect(); Channel channel = sshSession.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp) channel; info(" ftp Connected to " + host + ":" + port); } catch (JSchException e) { throw new RuntimeException("sftp連接失敗", e); } return sftp; } /** * 下載單個文件,如果指定文件名,則下載到文件名否則保持原有文件名 * * @param remoteFilePath 遠程文件路徑 /tmp/xxx.txt || xxx.txt.zip * @param localFilePath 本地文件路徑 如 D:\\xxx.txt * @return 下載的文件 */ public File downloadFile(String remoteFilePath, String localFilePath) { info(">>>>>>>>>downloadFile--ftp下載文件" + remoteFilePath + "開始>>>>>>>>>>>>>"); connect(); String remoteFileName = ""; // 遠端目錄確定以 / 作為目錄格式 String rFileSeparator = "/"; int rDirNameSepIndex = remoteFilePath.lastIndexOf(rFileSeparator) + 1; String rDir = remoteFilePath.substring(0, rDirNameSepIndex); remoteFileName = remoteFilePath.substring(rDirNameSepIndex); if(localFilePath.endsWith(File.separator)) { localFilePath = localFilePath + (localFilePath.endsWith(File.separator) ? remoteFileName : "/" + remoteFileName); } File file = null; OutputStream output = null; try { file = new File(localFilePath); if (file.exists()) { file.delete(); } file.createNewFile(); sftp.cd(rDir); output = new FileOutputStream(file); sftp.get(remoteFileName, output); info("===DownloadFile:" + remoteFileName + " success from sftp."); } catch (SftpException e) { error("ftp下載文件失敗", e); } catch (FileNotFoundException e) { error("本地目錄異常,請檢查" + file.getPath(), e); } catch (IOException e) { error("創建本地文件失敗" + file.getPath(), e); } finally { if (output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } disconnect(); } info(">>>>>>>>>downloadFile--ftp下載文件結束>>>>>>>>>>>>>"); return file; } /** * 上傳單個文件,如果指正下載文件名則使用,否則保留原有文件名 * * @param remoteFilePath 遠程文件路徑 /tmp/xxx.txt ||xxx.txt.zip * @param uploadFilePath 要上傳的文件 如:D:\\test\\xxx.txt */ public void uploadFile(String remoteFilePath, String uploadFilePath) { info(" begin uploadFile from:" + uploadFilePath + ", to: " + remoteFilePath); FileInputStream in = null; connect(); String remoteFileName = ""; String remoteDir = remoteFilePath; String localFileName = ""; // 遠端目錄確定以 / 作為目錄格式 String rFileSeparator = "/"; if(remoteFilePath.endsWith(rFileSeparator)) { localFileName = uploadFilePath.substring(uploadFilePath.lastIndexOf(File.separator) + 1); remoteFileName = localFileName; } else { int fileNameDirSep = remoteFilePath.lastIndexOf(rFileSeparator) + 1; remoteDir = remoteFilePath.substring(0, fileNameDirSep); remoteFileName = remoteFilePath.substring(fileNameDirSep); } try { sftp.cd(remoteDir); } catch (SftpException e) { try { sftp.mkdir(remoteDir); sftp.cd(remoteDir); } catch (SftpException e1) { error("ftp創建文件路徑失敗,路徑為" + remoteDir); throw new RuntimeException("ftp創建文件路徑失敗" + remoteDir); } } File file = new File(uploadFilePath); try { in = new FileInputStream(file); sftp.put(in, remoteFileName); } catch (FileNotFoundException e) { error("文件不存在-->" + uploadFilePath); } catch (SftpException e) { error("sftp異常-->", e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { info("Close stream error." + e.getMessage()); } } disconnect(); } info(">>>>>>>>>uploadFile--ftp上傳文件結束>>>>>>>>>>>>>"); } /** * 關閉連接 */ public void disconnect() { if (this.sftp != null) { if (this.sftp.isConnected()) { this.sftp.disconnect(); this.sftp = null; info("sftp 連接已關閉!"); } } if (this.sshSession != null) { if (this.sshSession.isConnected()) { this.sshSession.disconnect(); this.sshSession = null; info("sshSession 連接已關閉!"); } } } private void info(String msg) { System.out.println("info: " + msg); } private void error(String msg) { error(msg, null); } private void error(String msg, Throwable e) { System.out.println("error: " + msg); if(e != null) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { SftpUploadTest uploadTest = new SftpUploadTest("root", "123", "10.40.10.17", 52766); uploadTest.uploadFile("/tmp/" + "readme-" + System.currentTimeMillis() + ".txt", "C:\\Users\\xx\\Desktop\\sample\\readme.txt"); uploadTest.downloadFile("/tmp/readme.txt", "C:\\Users\\xx\\Desktop\\sample\\readme-" + System.currentTimeMillis() + ".txt"); } }
使用時,可根據需要進行連接的適時釋放!也可能為了安全需要,添加一些額外的安全指令!
sftp文件操作的命令羅列如下參考:
sftp常用的為上傳下載
# get # 從遠程服務器上下載一個文件存放到本地,如下: # 先通過lcd切換到本地那個目錄下,然后通過get file >> lcd d:\ #表示切換到本地的d盤下 >> get ./test.sql #這樣就將當前文件下載本地的d盤下 # put # 是將本地的文件上傳到遠程服務器上,如下: >> put #在windows下彈出選擇文件的窗口 # lcd # 先通過lcd切換到本地那個目錄下 >> lcd c:\ #表示切換到本地的c盤下 # lls #顯示當前目錄下的所有文件 >> pwd #顯示當前目錄