Windows搭建SFTP文件服务器
自己搭建一个SFTP文件服务器,来实现不同IP服务器之间文件的传输;
应用的场景:由于需要缓解服务器的压力,需要对服务进分离,分别放置在不同IP服务器上;
首先提供一个SFTP的工具,FreeSSHd,这个软件可以自行下载,安装的过程也是傻瓜式的,并没有什么可以说的至于对于服务器的配置,提醒以下几点:
1。默认是22端口,一般来说这个端口会被占用,所以我自己勾选的是23端口(红色框不勾选,如果勾选的话,并且之前选择作为一个系统服务的话,会创建另外一个实例,自己还是会以为是原来的那个服务器,结果导致实例创建不起来,最好把IP地址选上!!!)
2.创建一个自己的用户,
3.公用秘钥的勾选:
4.创建文件服务器默认的服务地址,可以进行勾选
5.其他的保持默认即可,记得要点击启动ssh服务!!!
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被占用,需要进行对端口所对应的任务杀死,或者是之前说的服务已成为系统服务,早就有一个实例(查看任务管理器还看不出来)