1.添加依赖
<!--ftp-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.1</version>
</dependency>
2.FtpUtil
@Data
@Component
public class FtpUtil {
/** 本地字符编码 */
private static String LOCAL_CHARSET = "GBK";
// FTP协议里面,规定文件名编码为iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1";
/**
* 日志对象
**/
private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);
/**
* 该目录不存在
*/
public static final String DIR_NOT_EXIST = "该目录不存在";
/**
* "该目录下没有文件
*/
public static final String DIR_CONTAINS_NO_FILE = "该目录下没有文件";
/**
* FTP地址
**/
@Value("${ftp.host}")
private String ip;
/**
* FTP端口
**/
@Value("${ftp.port}")
private int port;
/**
* FTP用户名
**/
@Value("${ftp.username}")
private String userName;
/**
* FTP密码
**/
@Value("${ftp.password}")
private String password;
// /**
// * FTP基础目录
// **/
// @Value("${ftp.basepath}")
// private String basePath;
//
// /**
// * 本地字符编码
// **/
// private static String localCharset = "GBK";
//
// /**
// * FTP协议里面,规定文件名编码为iso-8859-1
// **/
// private static String serverCharset = "ISO-8859-1";
//
// /**
// * UTF-8字符编码
// **/
// private static final String CHARSET_UTF8 = "UTF-8";
//
// /**
// * OPTS UTF8字符串常量
// **/
// private static final String OPTS_UTF8 = "OPTS UTF8";
//
// /**
// * 设置缓冲区大小4M
// **/
// private static final int BUFFER_SIZE = 1024 * 1024 * 4;
/**
* FTPClient对象
**/
private FTPClient ftpClient = null;
private FTPSClient ftps = null ;
/**
* 本地存储基础目录
**/
@Value("${logging.file.path}")
private String localPath;
//构造方法初始化类
public FtpUtil() {
}
//连接ftp
public boolean connectServer() throws Exception{
boolean flag = true;
if (ftpClient == null || !ftpClient.isConnected()) {
ftpClient = new FTPClient();
ftpClient.connect(ip,port);
log.info("Connected to " + ip);
log.info(ftpClient.getReplyString());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.warn("FTP server refused connection.");
return false ;
}
boolean bok = ftpClient.login(userName, password);
if (!bok) {
try {
ftpClient.disconnect() ;
ftpClient = null ;
} catch (Exception e) { }
throw new Exception("can not login ftp server") ;
}
ftpClient.setBufferSize(1024);
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setDataTimeout(120000);
ftpClient.enterLocalPassiveMode();
ftpClient.setUseEPSVwithIPv4(false);
ftpClient.setRemoteVerificationEnabled(false);
}
return flag;
}
//列出所有文件内容
public List<String> listRemoteAllFiles(String path) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
if (file.isFile()){
String name = file.getName();
String suffix = name.substring(name.lastIndexOf(".") + 1);
if(!"zip".equalsIgnoreCase(suffix)){
return false;
}
return true ;
}
return false ;
}}) ;
List<String> list = new ArrayList() ;
for (FTPFile file : files) {
list.add(file.getName()) ;
}
this.disConnect();
return list ;
}
public void disConnect() {
try {
if (ftpClient != null) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (Exception e) {
}
}
//下载文件
public boolean downloadFile(String remotePath, String fileName, String localPath) throws Exception {
FileOutputStream fos = null ;
try {
File localFile = new File(localPath, fileName);
fos = new FileOutputStream(localFile);
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(remotePath) ;
boolean bok = ftpClient.retrieveFile(fileName, fos);
fos.close() ;
fos = null ;
return bok ;
} catch (Exception e) {
throw e ;
}
finally {
if (fos!=null) {
try {
fos.close() ;
fos = null ;
} catch (Exception e2) { }
}
}
}
//上传文件
public boolean uploadFile(String remotePath, String filename, String localFilePath) throws Exception {
FileInputStream fis = null ;
try {
fis = new FileInputStream(new File(localFilePath));
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(remotePath);
boolean bok = ftpClient.storeFile(filename, fis);
fis.close();
fis = null ;
return bok ;
} catch (Exception e) {
throw e ;
}
finally {
if (fis!=null) {
try {
fis.close() ;
fis = null ;
} catch (Exception e2) { }
}
}
}
//删除文件
public boolean deleteFile(String remotePath, String filename) throws Exception {
ftpClient.changeWorkingDirectory(remotePath);
boolean bok = ftpClient.deleteFile(filename) ;
return bok ;
}
//列出指定日期戳之后的所有文件内容,只筛选zip类型文件,不包括文件夹,返回文件名列表
public List<String> fileListAfterTime(String path, Date timestamp) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
if (file.isFile()){
Calendar timestampR = file.getTimestamp();
Date date = timestampR.getTime();
if(timestamp!=null && date.getTime()<timestamp.getTime()){
return false;
}
String name = file.getName();
String suffix = name.substring(name.lastIndexOf(".") + 1);
if(!"zip".equalsIgnoreCase(suffix)){
return false;
}
return true;
}
return false ;
}}) ;
List<String> list = new ArrayList() ;
for (FTPFile file : files) {
String name = file.getName();
//String filePath = path + "/" +name;
list.add(name) ;
}
this.disConnect();
return list ;
}
//获取文件夹列表,业务需要文件夹name以“yyyy-MM-dd”命名,筛选掉name在指定日期之前的文件夹
public List<String> folderListAfterTime(String path, Date timestamp) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
FTPFile[] files = ftpClient.listFiles(path, new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
if (file.isDirectory()){
String name = file.getName();
try {
if(timestamp!=null){
Date date= new SimpleDateFormat("yyyy-MM-dd").parse(name);//字符串转成date对象类型
String format = new SimpleDateFormat("yyyy-MM-dd").format(timestamp);
Date startDate = getStartDate(format);
if(date.getTime()<startDate.getTime()){
return false;
}
}
} catch (ParseException e) {
e.printStackTrace();
return false;
}
return true ;
}
return false ;
}}) ;
List<String> list = new ArrayList() ;
for (FTPFile file : files) {
String name = file.getName();
//String filePath = path + "/" +name;
list.add(name) ;
}
this.disConnect();
return list ;
}
/**
* 获取日期开始时间
* @param date "2020-02-11"
* @return eg:"2020-02-11 00:00:00"
*/
public Date getStartDate(String date) {
if(date == null) {
return null;
}
try{
Calendar c = Calendar.getInstance();
c.setTime(DateUtils.parseDate(date, "yyyy-MM-dd"));
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
return c.getTime();
}catch (ParseException e){
return null;
}
}
/** 判断Ftp目录是否存在 */
public boolean isDirExist(String dir) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
boolean isExist;
try {
//判断目录是否存在
isExist = ftpClient.changeWorkingDirectory(dir);
System.out.println(isExist);
} catch (IOException e) {
e.printStackTrace();
isExist = false;
}
this.disConnect();
return isExist;
}
/**
* @Description 批量下载指定目录下面指定文件名list的文件
* @Param remotePath: 指定FTP上的目录
* @Param nameList: 文件名list
* @Param localPath: 本地目录
* @return boolean
*/
public List<String> downloadFile(String remotePath, List<String> nameList, String localPath) throws Exception {
List<String> fileList = new ArrayList<>();
this.connectServer();
ftpClient.enterLocalPassiveMode();
// 得到文件列表
FTPFile[] files = ftpClient.listFiles(remotePath, new FTPFileFilter() {
@Override
public boolean accept(FTPFile file) {
if (file.isFile()){
System.out.println(file.getName());
if(!nameList.contains(file.getName())){
return false;
}
return true ;
}
return false ;
}}) ;
//遍历
for (FTPFile file : files) {
FileOutputStream fos = null ;
try {
File localFile = new File(localPath+remotePath, file.getName());
// 判断目录是否存在
File dir = new File(localPath + remotePath);
if (!dir.exists()) {
dir.mkdirs();
}
fos = new FileOutputStream(localFile);
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(remotePath) ;
boolean bok = ftpClient.retrieveFile(new String(file.getName().getBytes(LOCAL_CHARSET), "iso-8859-1"), fos);
fos.close() ;
fos = null ;
//this.disConnect();
fileList.add(localPath+remotePath + "/" + file.getName());
} catch (Exception e) {
throw e ;
}
finally {
if (fos!=null) {
try {
fos.close() ;
fos = null ;
} catch (Exception e2) { }
}
}
}
this.disConnect();
return fileList;
}
//移动文件
public boolean removeFile(String remotePath) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
// 解析路径
String[] split = remotePath.split("/");
String bak_ = "/" + remotePath.split("/")[1] + "_bak";
String folder = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String bak_path = bak_ + "/" + folder;
// 判断目录是否存在
if (!this.CreateDirecroty(bak_path)) {
this.disConnect();
return false;
}
//开始移动
this.disConnect();
this.connectServer();
ftpClient.enterLocalPassiveMode();
String fileName = remotePath.substring(remotePath.lastIndexOf("/") + 1);
fileName = new String(fileName.getBytes(LOCAL_CHARSET), "iso-8859-1");
String filePath = bak_path + "/" + fileName;
String lib = remotePath.substring(0,remotePath.lastIndexOf("/"));
ftpClient.changeWorkingDirectory(lib);
ftpClient.rename(fileName,filePath);
//返回
if (!this.isDirExist(filePath)) {
this.disConnect();
return false;
}
this.disConnect();
return true;
}
//创建目录
public boolean makeDirectory(String dir,String folder) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
boolean flag = true;
try {
if(ObjectUtils.isNotEmpty(folder)){
ftpClient.changeWorkingDirectory(new String(folder));
}
flag = ftpClient.makeDirectory(dir);
if (flag) {
logger.debug("创建文件夹" + dir + " 成功!");
} else {
logger.debug("创建文件夹" + dir + " 失败!");
}
} catch (Exception e) {
e.printStackTrace();
}
this.disConnect();
return flag;
}
//创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
public boolean CreateDirecroty(String remote) throws Exception {
this.connectServer();
ftpClient.enterLocalPassiveMode();
boolean success = true;
String directory = remote + "/";
// String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
// 如果远程目录不存在,则递归创建远程服务器目录
if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory))) {
int start = 0;
int end = 0;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
String path = "";
String paths = "";
while (true) {
String subDirectory = new String(remote.substring(start, end).getBytes(LOCAL_CHARSET), "iso-8859-1");
String lib = path;
path = path + "/" + subDirectory;
if (!this.isDirExist(path)) {
if (!makeDirectory(subDirectory,lib)) {
logger.debug("创建目录[" + subDirectory + "]失败");
this.disConnect();
success = false;
}
}
this.disConnect();
this.connectServer();
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(path);
paths = paths + "/" + subDirectory;
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
if (end <= start) {
break;
}
}
}
this.disConnect();
return success;
}
}
3.注意事项:调试的时候发现调用disConnect后severlet置空了,但ftpclient并不为null,暂时没找到原因
网友评论