sftp和ftp 根据配置远程服务器地址下载文件到当前服务

时间:2021-01-04 09:54:22
package com.eastrobot.remote;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.eastrobot.util.PropertiesUtil;

/**
* full.zhang
*
* ftp/sftp抽象方法类
*
*/
public abstract class FileRemote {

private static final String FTP_MODE = "ftp";
private static final String SFTP_MODE = "sftp";

public static String ftproot;
public static String mode;
public static String host;
public static String username;
public static String password;
public static String port;

private static FileRemote client = null;

// 最大一次性下载50个文件
public static int max = 50;

private final static Log LOGGER = LogFactory.getLog(FileRemote.class);

public static FileRemote getInstance() {

if (client == null) {

ftproot = PropertiesUtil.getString("transfer.root");
mode = PropertiesUtil.getString("transfer.mode");
host = PropertiesUtil.getString("transfer.host");
username = PropertiesUtil.getString("transfer.username");
password = PropertiesUtil.getString("transfer.password");
port = PropertiesUtil.getString("transfer.port");

if (mode.equals(FTP_MODE)) {
client = new FileFtpRemote();
} else if (mode.equals(SFTP_MODE)) {
client = new FileSftpRemote();
}
}

return client;
}

/**
* 执行定时任务
*/
public void process() {

LOGGER.debug("----------------------------------------进入定时下载远程文件");

// 创建线程池
ExecutorService exec = Executors.newSingleThreadExecutor();

exec.execute(new Runnable() {
@Override
public void run() {

// 建立连接
initFtpInfo(host, port, username, password);

// 远程服务所有源文件路径集合
List<String> listSourcePath = listRemoteFilePath(ftproot);

if (listSourcePath.isEmpty()) {
LOGGER.debug("____________________释放连接");
client.closeConnection();
return;
}

if (listSourcePath.size() > max) {
listSourcePath = listSourcePath.subList(0, max);
}

for (String path : listSourcePath) {
downloadRemoteFile(path);
}

LOGGER.debug("____________________释放连接");
client.closeConnection();
}
});

exec.shutdown();
}

/**
* 初始化连接
*
* @param host
* @param port
* @param username
* @param password
* @throws Exception
* @return
*/
public abstract void initFtpInfo(String host, String port, String username, String password);

/**
* 下载远程服务下文件到本地服务
*
* @param path
* @return
* @throws Exception
*/
public abstract void downloadRemoteFile(String filePath);

/**
* 获取远程服务下指定目录下的所有文件路径集合(包含子目录下文件)
*
* @param path
* @return
*/
public abstract List<String> listRemoteFilePath(String path);

/**
* 释放连接
*/
public abstract void closeConnection();
}

package com.eastrobot.remote;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import com.eastrobot.command.Commander;

public class FileFtpRemote extends FileRemote {

protected FTPClient ftpClient;

private String encoding = "UTF-8";
private boolean binaryTransfer = true;

private final static Log LOGGER = LogFactory.getLog(FileFtpRemote.class);

@Override
public void initFtpInfo(String host, String port, String username, String password) {

try {

// 构造一个FtpClient实例
ftpClient = new FTPClient();

// 设置字符集
ftpClient.setControlEncoding(encoding);

// 连接FTP服务器
ftpClient.connect(host, StringUtils.isNotBlank(port) ? Integer.valueOf(port) : 21);

// 连接后检测返回码来校验连接是否成功
int reply = ftpClient.getReplyCode();

if (FTPReply.isPositiveCompletion(reply)) {

// 登陆到ftp服务器
if (ftpClient.login(username, password)) {
setFileType();
}
ftpClient.login(username, password);
} else {
ftpClient.disconnect();
LOGGER.error("ftp服务拒绝连接!");
}

} catch (Exception e) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect(); // 断开连接
} catch (IOException e1) {
LOGGER.error("ftp服务连接断开失败!");
}

}
LOGGER.error("ftp服务连接失败!");
}
}

/**
* 设置文件传输类型
*/
private void setFileType() {
try {
if (binaryTransfer) {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
} else {
ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
}
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void downloadRemoteFile(String filePath) {

if (StringUtils.endsWith(filePath, "/") || StringUtils.endsWith(filePath, File.separator)) {
filePath = filePath.substring(0, filePath.length() - 1);
}

File saveFile = new File(filePath);

if (saveFile.exists()) {
return;
}

// 文件所在目录
String path = filePath.substring(0, filePath.lastIndexOf("/"));

if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

OutputStream output = null;
try {

// 创建目标文件路径
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}

saveFile.createNewFile();

// 转移到FTP服务器目录
ftpClient.changeWorkingDirectory(path);
output = new FileOutputStream(saveFile);
ftpClient.retrieveFile(filePath, output);
} catch (IOException e) {
LOGGER.debug("文件:" + filePath + "______________________下载失败!");
e.printStackTrace();
} finally {
LOGGER.debug("文件:" + filePath + "______________________下载成功!");
IOUtils.closeQuietly(output);
}

}

@Override
public List<String> listRemoteFilePath(String path) {

List<String> list = new ArrayList<String>();

try {

if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {
if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

boolean changedir = ftpClient.changeWorkingDirectory(path);
if (changedir) {
ftpClient.setControlEncoding(encoding);
FTPFile[] files = ftpClient.listFiles();
for (FTPFile file : files) {

if (list.size() >= max) {
break;
}

if (file.isDirectory()) {
if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

list.addAll(this.listRemoteFilePath(path + file.getName()));
} else if (changedir) {
if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

File saveFile = new File(path + file.getName());
if (!saveFile.exists()) {
list.add(path + file.getName());
}
}
}

}

} catch (Exception e) {
e.printStackTrace();
}

return list;
}

@Override
public void closeConnection() {

if (ftpClient != null) {
try {
ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

}

package com.eastrobot.remote;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.eastrobot.command.Commander;
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 FileSftpRemote extends FileRemote {

protected Session session = null;
protected ChannelSftp channel = null;

private final static Log LOGGER = LogFactory.getLog(FileSftpRemote.class);

@Override
public void initFtpInfo(String host, String port, String username, String password) {
try {
JSch jsch = new JSch(); // 创建JSch对象
session = jsch.getSession(username, host, StringUtils.isNotBlank(port) ? Integer.valueOf(port) : 22);
session.setPassword(password); // 设置密码

Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(60000); // 设置timeout时间
session.connect(); // 通过Session建立链接

Channel chan = session.openChannel("sftp"); // 打开SFTP通道
chan.connect(); // 建立SFTP通道的连接

channel = (ChannelSftp) chan;
} catch (Exception e) {
LOGGER.error("sftp连接失败");
e.printStackTrace();
}
}

@Override
public void downloadRemoteFile(String filePath) {

if (StringUtils.endsWith(filePath, "/") || StringUtils.endsWith(filePath, File.separator)) {
filePath = filePath.substring(0, filePath.length() - 1);
}

File saveFile = new File(filePath);
FileOutputStream output = null;

try {

if (saveFile.exists()) {
return;
}

// 创建目标文件路径
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}

saveFile.createNewFile();

// 文件所在目录
String path = filePath.substring(0, filePath.lastIndexOf("/"));

if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

channel.cd(path);

channel.get(filePath, new FileOutputStream(saveFile));

LOGGER.debug("文件:" + filePath + "____________________________________________下载成功!");
} catch (Exception e) {
LOGGER.debug("文件:" + filePath + "____________________________________________下载失败!");
e.printStackTrace();
} finally {
IOUtils.closeQuietly(output);
}

}

@SuppressWarnings("unchecked")
@Override
public List<String> listRemoteFilePath(String path) {

List<String> list = new ArrayList<String>();
Vector<LsEntry> v = null;
try {

if (!StringUtils.endsWith(path, "/") && StringUtils.endsWith(path, File.separator)) {
path = path + File.separator;
}

v = channel.ls(path);
} catch (SftpException e) {
e.printStackTrace();
}
for (LsEntry lsEntry : v) {

if (list.size() >= max) {
break;
}

if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
SftpATTRS attrs = lsEntry.getAttrs();
if (attrs.isDir()) {

if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}
list.addAll(this.listRemoteFilePath(path + lsEntry.getFilename()));
} else {

if (!StringUtils.endsWith(path, "/") && !StringUtils.endsWith(path, File.separator)) {

if (Commander.isLinux) {
path = path + File.separator;
} else {
path = path + "/";
}
}

File saveFile = new File(path + lsEntry.getFilename());
if (!saveFile.exists()) {
list.add(path + lsEntry.getFilename());
}
}
}
}

return list;
}

@Override
public void closeConnection() {
try {
if (channel != null) {
channel.quit();
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}

public Session getSession() {
return session;
}

public void setSession(Session session) {
this.session = session;
}

public ChannelSftp getChannel() {
return channel;
}

public void setChannel(ChannelSftp channel) {
this.channel = channel;
}

}