由於公司項目的需要,需要自己搭建一個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被占用,需要進行對端口所對應的任務殺死,或者是之前說的服務已成為系統服務,早就有一個實例(查看任務管理器還看不出來)
最后,謝謝大家的閱讀,希望可以有所收獲
