由於公司項目的需要,需要自己搭建一個SFTP文件服務器,來實現不同IP服務器之間文件的傳輸;
應用的場景:由於需要緩解服務器的壓力,需要對服務進分離,分別放置在不同IP服務器上;
首先提供一個SFTP的工具,FreeSSHd,這個軟件可以自行下載,安裝的過程也是傻瓜式的,並沒有什么可以說的
至於對於服務器的配置,提醒以下幾點:
1。默認是22端口,一般來說這個端口會被占用,所以我自己勾選的是23端口(紅色框不勾選,如果勾選的話,並且之前選擇作為一個系統服務的話,
會創建另外一個實例,自己還是會以為是原來的那個服務器,結果導致實例創建不起來)
2.創建一個自己的用戶,
3.公用秘鑰的勾選:
4.創建文件服務器默認的服務地址,可以進行勾選
5.其他的保持默認即可;
6.提供一個連接服務器的工具類
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Vector; import org.apache.log4j.Logger; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpATTRS; import com.jcraft.jsch.SftpException; import com.jcraft.jsch.ChannelSftp.LsEntry; public class SFTPUtils { private static Logger log = Logger.getLogger(SFTPUtils.class.getName()); private String host;//服務器連接ip private String username;//用戶名 private String password;//密碼 private int port = 22;//端口號 private static ChannelSftp sftp = null; private Session sshSession = null; public SFTPUtils(){} public SFTPUtils(String host, int port, String username, String password) { this.host = host; this.username = username; this.password = password; this.port = port; } /** * 通過SFTP連接服務器 */ public void connect() { try { JSch jsch = new JSch(); jsch.getSession(username, host, port); sshSession = jsch.getSession(username, host, port); if (log.isInfoEnabled()) { log.info("Session created."); } sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect(); if (log.isInfoEnabled()) { log.info("Session connected."); } Channel channel = sshSession.openChannel("sftp"); channel.connect(); if (log.isInfoEnabled()) { log.info("Opening Channel."); } sftp = (ChannelSftp) channel; if (log.isInfoEnabled()) { log.info("Connected to " + host + "."); } } catch (Exception e) { e.printStackTrace(); } } /** * 關閉連接 */ public void disconnect() { if (this.sftp != null) { if (this.sftp.isConnected()) { this.sftp.disconnect(); if (log.isInfoEnabled()) { log.info("sftp is closed already"); } } } if (this.sshSession != null) { if (this.sshSession.isConnected()) { this.sshSession.disconnect(); if (log.isInfoEnabled()) { log.info("sshSession is closed already"); } } } } /** * 上傳單個文件 * @param remotePath:遠程保存目錄 * @param remoteFileName:保存文件名 * @param localPath:本地上傳目錄(以路徑符號結束) * @param localFileName:上傳的文件名 * @return */ public boolean uploadFile(String remotePath, String remoteFileName,String localPath, String localFileName) { FileInputStream in = null; try { createDir(remotePath); File file = new File(localPath + localFileName); in = new FileInputStream(file); sftp.put(in, remoteFileName); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (SftpException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 創建目錄 * @param createpath * @return */ public boolean createDir(String createpath) { try { if (isDirExist(createpath)) { sftp.cd(createpath); return true; } String pathArry[] = createpath.split("/"); StringBuffer filePath = new StringBuffer("/"); for (String path : pathArry) { if (path.equals("")) { continue; } filePath.append(path + "/"); if (isDirExist(filePath.toString())) { sftp.cd(filePath.toString()); } else { // 建立目錄 sftp.mkdir(filePath.toString()); // 進入並設置為當前目錄 sftp.cd(filePath.toString()); } } sftp.cd(createpath); return true; } catch (SftpException e) { e.printStackTrace(); } return false; } /** * 判斷目錄是否存在 * @param directory * @return */ public boolean isDirExist(String directory) { boolean isDirExistFlag = false; try { SftpATTRS sftpATTRS = sftp.lstat(directory); isDirExistFlag = true; return sftpATTRS.isDir(); } catch (Exception e) { if (e.getMessage().toLowerCase().equals("no such file")) { isDirExistFlag = false; } } return isDirExistFlag; }
7.測試連接是否異常,這里說明一下參數的問題
創建文件服務器的連接時,參數依次為IP,端口,戶名,密碼,就是之前自己配置的那些信息
上傳文件的方法中:
第一個參數是相對與自己之前創建文件服務器的地址,如果沒有,會自行對文件進行創建,
第二個參數是保存文件的名稱,可以自行定義;
第三個參數是本地文件的路徑,選擇上傳的文件會在這個地址下進行查找,如果配置錯誤,會報出文件不存在的錯誤;
第四個參數是本地文件在文件服務器地址下的名稱,也就是上傳文件的名稱,如果沒有這個文件的話,肯定會報錯的哦;
public static void main(String[] args) { SFTPUtils sftp = null; try { sftp = new SFTPUtils("127.0.0.1",23,"shishi", "123456");//現在后台的SFTP的賬戶信息 sftp.connect(); // 下載 //boolean flag = sftp.uploadFile("/test/", "201708081138_o7Lpot_9nrAvyz2dbLFbq7ftn374_ba89d4.jpg", "F:/", "201708081138_o7Lpot_9nrAvyz2dbLFbq7ftn374_ba89d4.jpg"); //上傳文件 //System.out.println(flag); } catch (Exception e) { e.printStackTrace(); } finally { sftp.disconnect(); } }
8.如果出現端口占用或者IP被占用,需要進行對端口所對應的任務殺死,或者是之前說的服務已成為系統服務,早就有一個實例(查看任務管理器還看不出來)
最后,謝謝大家的閱讀,希望可以有所收獲