需求说明:有两个服务器,一个是A文件服务器(生产用),一个是B文件服务器(备份用)
要求把A服务器上每天新增的文件备份到B服务器上
写在前面的话:1.代码来源于网络,是我自己整理的。
2.网络上的知识点太零散,找了好多博客,完成了我的需求。
3.本着技术共享的原则,发了这篇博客。
先在B服务器上安装freeSSHD工具,进行用户名和密码,端口等配置
package com.ssh.backup;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import com.ssh.Api.ConnectSftp;
/**
* 需求说明:有两个服务器,一个是A文件服务器(生产用),一个是B文件服务器(备份用)
* 要求把A服务器上每天新增的文件备份到B服务器上
* 在B服务器上安装freeSSHD工具,进行用户名和密码,端口等配置
* */
public class BackupFile {
public static void main(String[] args) {
String ip = "192.168.1.***";//B服务器的ip
String user = "test"; //freeSSHD Users
String pwd = "12qwaszx"; //freeSSHD 密码
int port = 222; //freeSSHD 端口
String disk = "D:"; //磁盘
ConnectSftp.theBackupFile(ip,user,pwd,port,disk);
}
}
package com.ssh.Api;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
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.ssh.pojo.UploadFile;
/**
* 链接sftp
* */
public class ConnectSftp {
/**
* 文件备份
* */
public static void theBackupFile(String ip,String user,String psw,int port,String disk){
try {
Session session = null;
JSch jsch = new JSch();
if (port <= 0) {
// 连接服务器,采用默认端口
session = jsch.getSession(user, ip);
} else {
// 采用指定的端口连接服务器
session = jsch.getSession(user, ip, port);
}
// 如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
// 设置登陆主机的密码
session.setPassword(psw);// 设置密码
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
// 设置登陆超时时间
session.connect(300000);
queryUpLoadFile(session,disk);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询文件并创建文件夹
* @param session jsch的session
* @param disk 磁盘 D
* */
public static void queryUpLoadFile(Session session,String disk) {
Channel channel = null;
try {
channel = (Channel) session.openChannel("sftp");
channel.connect(10000000);
ChannelSftp sftp = (ChannelSftp) channel;
String pwd = sftp.pwd();// "/"
//今天备份昨天的数据
SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
Date beginDate = new Date();
Calendar date = Calendar.getInstance();
date.setTime(beginDate);
date.set(Calendar.DATE, date.get(Calendar.DATE) - 1);
String yesterday = dft.format(date.getTime());
//查询数据库昨天上传的文件
List<UploadFile> list = queryFile(yesterday);
if(list!=null&&!list.isEmpty()&&list.size()>0){
for(UploadFile uf:list) {
String path = uf.getPath();
String uuid = uf.getUuid();
String extensionName = uf.getExtensionName();
String sPath = disk+path+"/"+uuid;
String[] split = path.split("/");
String dPath=split[2];
//第一次备份时判断文件夹是否存在
if(isDirExist(dPath,sftp)){
sftp.cd(dPath);
}else{
newFolder(dPath,sftp);//创建文件夹
}
File file = new File(sPath);
if(file.exists()){
copyFile(sftp, file, pwd);
}else{
//带着后缀名再查一次
String pathz = disk+path+"/"+uuid+extensionName;
File filez = new File(pathz);
if(filez.exists()){
copyFile(sftp, filez, pwd);
}else{
//查看A服务器是否有对应的文件,你本地就是A服务器,在D盘找 D:\\uploadFile\test\9f9ceaad-eabe-4d93-8fb9-0b8d1243e399 是否存在
System.out.println("The specified file was not found");
}
}
}
}
}catch (Exception e) {
e.printStackTrace();
}finally {
session.disconnect();
channel.disconnect();
}
}
/**
* 判断文件夹存在
* */
public static boolean isDirExist(String directory,ChannelSftp sftp) {
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;
}
/**
* 新建文件夹
* mkdir(): 创建目录
* cd(): 进入指定目录
* put(): 文件上传
* get(): 文件下载
* ls(): 得到指定目录下的文件列表
* rename(): 重命名指定文件或目录
* rm(): 删除指定文件
* rmdir(): 删除目录
* */
public static void newFolder(String createpath, ChannelSftp sftp) {
try {
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(),sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
sftp.cd(createpath);
} catch (SftpException e) {
}
}
/**
* 复制文件到B服务器
* */
public static void copyFile(ChannelSftp sftp, File file, String pwd) {
InputStream instream = null;
OutputStream outstream = null;
try {
outstream = sftp.put(file.getName());
instream = new FileInputStream(file);
byte b[] = new byte[10240];
int n;
while ((n = instream.read(b)) != -1){
outstream.write(b, 0, n);
}
} catch (SftpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outstream.flush();
outstream.close();
instream.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* @param yesterday 昨天
* 这里不连数据库取数据了,手动写两条模拟一下。
* 在你本机D盘新建uploadFile文件夹,在建test文件夹,放两个文件 名字是uf1.setuuid和uf2.setuuid的值
* 数据库语句:
* <select id="queryFile" resultMap="BaseResultMap" >
* SELECT * from t_upload_file WHERE to_date(TIME,'yyyy-mm-dd hh24:mi:ss')
* BETWEEN to_Date('${yesterday} 00:00:00','yyyy-mm-dd hh24:mi:ss')
* AND to_Date('${yesterday} 23:59:59','yyyy-mm-dd hh24:mi:ss') ORDER BY ID
* </select>
* */
public static List<UploadFile> queryFile(String yesterday){
List<UploadFile> list = new ArrayList<>();
UploadFile uf1 = new UploadFile();
uf1.setUuid("9f9ceaad-eabe-4d93-8fb9-0b8d1243e399");
uf1.setName("test1.jpg");
uf1.setPath("/uploadFile/test");
uf1.setExtensionName(".jpg");
list.add(uf1);
UploadFile uf2 = new UploadFile();
uf2.setUuid("2f215921-3989-412b-b05c-dc04b46325d3");
uf2.setName("test2.jpg");
uf2.setPath("/uploadFile/test");
uf2.setExtensionName(".jpg");
list.add(uf2);
return list;
}
}