本地地址 服务器 地址 账户 密码 地址 端口 更新时间 设置成参数
public class SftpFileUploader {
private String localSourceDirectory;
private String remoteDestinationDirectory;
private String username;
private String hostname;
private int port;
private String password;
private long uploadIntervalMinutes;
public SftpFileUploader(String localSourceDirectory, String remoteDestinationDirectory,
String username, String hostname, int port, String password,
long uploadIntervalMinutes) {
this.localSourceDirectory = localSourceDirectory;
this.remoteDestinationDirectory = remoteDestinationDirectory;
this.username = username;
this.hostname = hostname;
this.port = port;
this.password = password;
this.uploadIntervalMinutes = uploadIntervalMinutes;
}
// 定时任务
public void startPeriodicUpload() {
// lambda表达式创建 uploadFiles任务
Runnable uploadTask = this::uploadFiles;
// 首次运行上传文件,方便手动测试
uploadTask.run();
// 设置定时任务,每隔uploadIntervalMinutes分钟执行一次上传操作
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(uploadTask, uploadIntervalMinutes, uploadIntervalMinutes, TimeUnit.MINUTES);
/**
*
* scheduleAtFixedRate方法接受四个参数:
*
* uploadTask: 要执行的任务,这里是this::uploadFiles。
* initialDelay: 首次执行任务的延迟时间,设为0表示立即开始执行。
* period: 每次执行任务的时间间隔。
* unit: 时间间隔的单位,这里是TimeUnit.MINUTES,表示时间间隔是以分钟为单位。
*
* */
}
private void uploadFiles() {
JSch jsch = new JSch();
Session session = null;
ChannelSftp channelSftp = null;
try {
session = jsch.getSession(username, hostname, port); //建立SSH连接
session.setPassword(password); // 将密码设置到已建立的会话中,以便在连接时进行身份验证。
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");//打开一个通道,指定通道的类型为sftp
/**
* 因为返回的通道对象是通用的Channel类型,
* 我们需要将它强制转换成ChannelSftp类型,
* 这样我们才能使用SFTP通道特有的方法。
* 强制转换是为了将通用的Channel对象转换为我们需要的特定类型,
* 这样就可以调用特定类型的方法了
* */
channelSftp.connect();
File sourceDirectory = new File(localSourceDirectory); //表示本地源目录
uploadDirectory(channelSftp, sourceDirectory, remoteDestinationDirectory);//将本地源目录中的文件和子目录上传到服务器的对应远程目录。
/**
* 三个参数:(SFTP通道)、
* (本地源目录channelSftp的sourceDirectory对象File) )
* 和remoteDestinationDirectory(服务器目标目录路径)。
* */
} catch (JSchException | SftpException e) {
System.err.println("Error uploading file: " + e.getMessage());
} finally {
if (channelSftp != null && channelSftp.isConnected()) {
channelSftp.disconnect(); //通道断开
}
if (session != null && session.isConnected()) {
session.disconnect();//关闭服务链接
}
}
}
//上传本地目录和其中的文件到服务器的方法。
private void uploadDirectory(ChannelSftp channelSftp, File localDirectory, String remoteDirectory) throws SftpException {
channelSftp.cd(remoteDirectory);//进入到服务器上的对应远程目录
//获取本地目录下的所有文件和子目录
File[] files = localDirectory.listFiles();
//上传本地目录及其中的文件和子目录到服务器
if (files != null) { //首先,检查files是否为空
for (File file : files) {
if (file.isDirectory()) { //如果当前文件是一个目录(文件夹),则进入此分支
String remoteSubDirectory = remoteDirectory + "/" + file.getName();
//创建一个remoteSubDirectory字符串,表示要在服务器上创建的子目录路径。这个子目录的名称与当前本地目录名称相同
try {
channelSftp.cd(remoteSubDirectory);
} catch (SftpException e) {
channelSftp.mkdir(remoteSubDirectory);
channelSftp.cd(remoteSubDirectory);//无论目录是否存在,我们都切换到这个目录,准备上传其中的文件和子目录。
}
uploadDirectory(channelSftp, file, remoteSubDirectory);
// 电梯调用uploadDirectory方法,
// 创建当前目录的channelSftp、本地目录file,
// 以及在服务器上对应的子目录路径remoteSubDirectory。
// 这样就可以将当前本地目录下的文件和子目录上传到服务器的对应子目录中。
} else if (file.isFile()) {//如果当前是一个文件不是一个目录
uploadSingleFile(channelSftp, file, remoteDirectory);
/**
* 调用uploadSingleFile方法,
* 将当前文件上传到服务器的对应目录。
* remoteDirectory参数表示当前服务器目录路径。
* */
}
}
}
}
//用于将单个文件上传到服务器的对应目录
private void uploadSingleFile(ChannelSftp channelSftp, File localFile, String remoteDirectory) throws SftpException {
String remoteFilePath = remoteDirectory + "/" + localFile.getName();
channelSftp.put(localFile.getAbsolutePath(), remoteFilePath, ChannelSftp.APPEND);
System.out.println("File '" + localFile.getName() + "' uploaded successfully.");
}
}
启动类
public class Application {
public static void main(String[] args) {
List<String> localSourceDirectories = new ArrayList<>();
localSourceDirectories.add("");
localSourceDirectories.add("");
String remoteDestinationDirectory = "";
String username = "";
String hostname = "";
int port = 22;
String password = "";
long uploadIntervalMinutes = 1; // 每5分钟上传一次
FileUploaderUtils fileUploader = new FileUploaderUtils(localSourceDirectories, remoteDestinationDirectory,
username, hostname, port, password, uploadIntervalMinutes);
fileUploader.startPeriodicUpload();
}
}