package com.lianlian.cbfin.chnlgw.risk.common.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import com.lianlian.cbfin.chnlgw.yintong.api.common.enums.ResultCodeEnum;
import com.lianlian.cbfin.chnlgw.yintong.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FtpUtils {
private String host;
private Integer port;
private String username;
private String password;
private Integer timeout;
private static FtpUtils ftpUtils;
private FtpUtils(){}
private FtpUtils(String host, Integer port, String username, String password, Integer timeout) {
this.host = host;
this.port = port;
this.password = password;
this.username = username;
this.timeout = timeout;
}
public static FtpUtils getInstance(String host, Integer port, String username, String password, Integer timeout) {
if(ftpUtils == null) {
ftpUtils = new FtpUtils(host, port, username, password, timeout);
}
return ftpUtils;
}
private FTPClient getFTPClient() {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
ftpClient.connect(host, port);
ftpClient.login(username, password);
ftpClient.setConnectTimeout(timeout);
ftpClient.setControlKeepAliveReplyTimeout(5000);
ftpClient.setControlKeepAliveTimeout(15);
ftpClient.setSoTimeout(60000);
ftpClient.setDataTimeout(3600 * 1000);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.info("未连接到FTP,用户名或密码错误");
ftpClient.disconnect();
} else {
log.info("FTP连接成功");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return ftpClient;
}
public List<String> getFileNameList(String ftpPath) {
FTPClient ftpClient = null;
try {
log.info("从ftp目录{}获取文件列表", ftpPath);
ftpClient = getFTPClient();
ftpClient.changeWorkingDirectory(ftpPath);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
List<String> dfsFileNames = Arrays.stream(ftpFiles).map(FTPFile::getName).collect(Collectors.toList());
log.info("从ftp目录{}获取文件列表成功,文件列表{}", ftpPath, JSON.toJSONString(dfsFileNames));
ftpClient.logout();
return dfsFileNames;
} catch (Exception e) {
log.error("获取文件列表异常,异常信息:{}", e.getMessage());
throw new BizException(ResultCodeEnum.DOWNLOAD_FILE_ERROR, e.getMessage());
} finally {
if (ftpClient != null && ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
log.error("获取文件列表异常,异常信息:{}", e.getMessage(), e);
}
}
}
}
public boolean downloadFile(String ftpPath, String fileName, String localPath) {
OutputStream os = null;
FTPClient ftpClient = null;
try {
boolean flag = false;
File dir = new File(localPath);
if (!dir.exists()) {
dir.mkdir();
}
log.info("从ftp目录{}开始下载文件{}到{}", ftpPath, fileName, localPath);
ftpClient = getFTPClient();
ftpClient.changeWorkingDirectory(ftpPath);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for(FTPFile file : ftpFiles){
if(fileName.equalsIgnoreCase(file.getName())){
File localFile = new File(localPath + File.separator + file.getName());
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.flush();
os.close();
flag = true;
}
}
ftpClient.logout();
if(flag) {
log.info("{}下载文件成功", fileName);
}
else {
log.info("在{}下找不到{}文件", ftpPath, fileName);
throw new BizException(ResultCodeEnum.NOT_FOUND_FILE);
}
} catch (Exception e) {
log.error("下载文件异常,异常信息:{}", e.getMessage());
throw new BizException(ResultCodeEnum.DOWNLOAD_FILE_ERROR, e.getMessage());
} finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ftpClient != null) {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
return true;
}
public boolean uploadFile(String ftpPath, String fileName, String localPath) throws Exception{
log.info("从{}开始上传文件{}到ftp目录{}", localPath, fileName, ftpPath);
FTPClient ftpClient = null;
InputStream is = null;
boolean flag = false;
try {
ftpClient = getFTPClient();
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
if(!ftpClient.changeWorkingDirectory(ftpPath)){
ftpClient.makeDirectory(ftpPath);
}
ftpClient.changeWorkingDirectory(ftpPath);
is = new FileInputStream(new File(localPath + File.separator + fileName));
String tempName = ftpPath + "/" + fileName;
flag = ftpClient.storeFile(new String(tempName.getBytes("UTF-8"),"ISO-8859-1"), is);
if(flag){
log.info("上传文件成功");
}else{
log.error("上传文件失败");
}
} catch (Exception e) {
log.error("上传文件异常,异常信息:{}", e.getMessage());
throw new BizException(ResultCodeEnum.UPLOAD_FILE_ERROR, e.getMessage());
} finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ftpClient != null) {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
return flag;
}
public boolean downloadFileByBreakPoint(String ftpPath, String fileName, String localPath) {
OutputStream os = null;
InputStream in = null;
FTPClient ftpClient = getFTPClient();
try {
boolean flag = false;
File dir = new File(localPath);
if (!dir.exists()) {
dir.mkdir();
}
long localFileLength = 0;
File localFile = new File(localPath + File.separator + fileName);
if (localFile.exists()) {
localFileLength = localFile.length();
}
log.info("从ftp目录{}开始下载文件{}到{}", ftpPath, fileName, localPath);
ftpClient.changeWorkingDirectory(ftpPath);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for(FTPFile file : ftpFiles){
if(fileName.equalsIgnoreCase(file.getName())){
if (file.getSize() <= localFileLength) {
return true;
}
os = new FileOutputStream(localFile, true);
ftpClient.setRestartOffset(localFileLength);
in = ftpClient.retrieveFileStream(((new String(fileName.getBytes("UTF-8"), "iso-8859-1"))));
byte[] bytes = new byte[5120];
int c;
while ((c = in.read(bytes)) != -1) {
os.write(bytes, 0, c);
}
os.flush();
flag = true;
}
}
if(flag) {
log.info("{}下载文件成功", fileName);
}
else {
log.info("在{}下找不到{}文件", ftpPath, fileName);
throw new BizException(ResultCodeEnum.NOT_FOUND_FILE);
}
} catch (Exception e) {
log.error("下载文件异常,异常信息:{}", e.getMessage(), e);
throw new BizException(ResultCodeEnum.DOWNLOAD_FILE_ERROR, e.getMessage());
} finally {
if(in != null){
try {
in.close();
ftpClient.completePendingCommand();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ftpClient != null) {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
log.info("下载文件流程结束");
return true;
}
public void deleteFile(String ftpPath, String fileName) {
log.info("从ftp目录{}开始删除文件{}", ftpPath, fileName);
FTPClient ftpClient = null;
boolean flag;
try {
ftpClient = getFTPClient();
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(ftpPath);
flag = ftpClient.deleteFile(ftpPath + fileName);
if (flag) {
log.info("删除文件成功");
} else {
log.error("删除文件失败");
}
} catch (Exception e) {
log.error("删除文件异常,异常信息:{}", e.getMessage());
throw new BizException(ResultCodeEnum.UPLOAD_FILE_ERROR, e.getMessage());
} finally {
if (ftpClient != null && ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
log.error("删除文件异常,异常信息:{}", e.getMessage(), e);
}
}
}
}
}