package com.bfb.gateway.payment.service.utils;
import com.bfb.gateway.payment.entity.model.exception.PaymentException;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.SocketException;
import java.text.ParseException;
public class FtpUtils {
private static final Logger logger = LoggerFactory.getLogger(FtpUtils.class);
private FTPClient ftpClient;
/**
* init ftp servere
*/
public FtpUtils(String ip, int port, String userName, String userPwd) {
this.connectServer(ip, port, userName, userPwd);
}
public FtpUtils() {
}
/**
* @param ip
* @param port
* @param userName
* @param userPwd
* @throws java.net.SocketException
* @throws java.io.IOException 连接到服务器
*/
public FTPClient connectServer(String ip, int port, String userName, String userPwd) {
ftpClient = new FTPClient();
try {
// 连接
ftpClient.connect(ip, port);
// 登录
if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
ftpClient.login(userName, userPwd);
}else{
ftpClient.disconnect();
}
} catch (SocketException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
}
return ftpClient;
}
/**
* @throws java.io.IOException 关闭连接
*/
public void closeServer() {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
}
/**
* 从FTP服务器上下载文件,支持断点续传
* @param remotePath 远程文件路径
* @param localPath 本地文件路径
* @return 上传的状态
* @throws java.io.IOException
*/
public int downAllFiles(String remotePath, String localPath, String remoteEncoding, String fileEncoding) {
logger.info("文件下载本地路径{},远程路径{},远程文件编码{},本地文件编码{}",localPath,remotePath,remoteEncoding,fileEncoding);
try {
// 设置被动模式
ftpClient.enterLocalPassiveMode();
// 设置以二进制方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 检查远程文件是否存在
FTPFile[] files = ftpClient.listFiles(new String(remotePath.getBytes(fileEncoding), remoteEncoding));
if (files.length < 1) {
logger.error("远程文件不存在");
}
// 跳转到指定目录
if (remotePath != null && remotePath.length() > 0) {
ftpClient.changeWorkingDirectory(remotePath);
}
// 判断本地文件夹是否方存在
File localDir = new File(localPath);
if (!localDir.exists()) {
localDir.mkdirs();
}
int count = 0;
for (FTPFile ff : files) {
long lRemoteSize = ff.getSize();
String fildName = ff.getName();
// 本地存在文件,进行断点下载
File f = new File(localPath + File.separator + fildName);
if (f.exists()) {
long localSize = f.length();
if (localSize >= lRemoteSize) {
logger.info("本地文件[{}]大于远程文件,下载中止", fildName);
}
// 进行断点续传,并记录状态
FileOutputStream out = new FileOutputStream(f, true);
ftpClient.setRestartOffset(localSize);
InputStream in = ftpClient.retrieveFileStream(new String(fildName.getBytes(fileEncoding), remoteEncoding));
byte[] bytes = new byte[1024];
int c;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
}
in.close();
out.close();
boolean isDo = ftpClient.completePendingCommand();
if (isDo) {
logger.info("[{}]文件下载完毕", fildName);
count++;
} else {
logger.info("[{}]文件下载失败", fildName);
}
} else {
OutputStream out = new FileOutputStream(f);
InputStream in = ftpClient.retrieveFileStream(new String(fildName.getBytes(fileEncoding), remoteEncoding));
byte[] bytes = new byte[1024];
int c;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
}
in.close();
out.close();
boolean upNewStatus = ftpClient.completePendingCommand();
if (upNewStatus) {
logger.info("[{}]文件下载完毕", fildName);
count++;
} else {
logger.info("[{}]文件下载失败", fildName);
}
}
}
return count;
} catch (IOException e) {
logger.error(e.getMessage());
return 0;
} finally {
closeServer();
}
}
/**
* 从FTP服务器上下载文件,支持断点续传
* @param remotePath 远程文件路径
* @param localPath 本地文件路径
* @return 上传的状态
* @throws IOException
*/
public int downFile(String remotePath, String localPath, String remoteEncoding, String fileEncoding,String fileName) throws PaymentException {
logger.info("文件下载本地路径{},远程路径{},远程文件编码{},本地文件编码{},文件名称{}",localPath,remotePath,remoteEncoding,fileEncoding,fileName);
try {
// 设置被动模式
ftpClient.enterLocalPassiveMode();
// 设置以二进制方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 检查远程文件是否存在
FTPFile[] files = ftpClient.listFiles(new String(remotePath.getBytes(fileEncoding), remoteEncoding));
if (files.length < 1) {
logger.error("远程文件不存在");
throw new PaymentException(ConstantsPaymentRetCode.CHECK_FILE_ERROR_DOWNLOAD);
}
boolean flag=false;
for (FTPFile ff : files){
if(fileName.equals(ff.getName())){
flag=true;
break;
}
}
if(!flag){
logger.error("远程文件不存在");
throw new PaymentException(ConstantsPaymentRetCode.CHECK_FILE_ERROR_DOWNLOAD);
}
// 跳转到指定目录
if (remotePath != null && remotePath.length() > 0) {
ftpClient.changeWorkingDirectory(remotePath);
}
// 判断本地文件夹是否方存在
File localDir = new File(localPath);
if (!localDir.exists()) {
localDir.mkdirs();
}
int count = 0;
// 本地存在文件,进行断点下载
File f = new File(localPath + File.separator + fileName);
if (f.exists()) {
long localSize = f.length();
// 进行断点续传,并记录状态
FileOutputStream out = new FileOutputStream(f, true);
ftpClient.setRestartOffset(localSize);
InputStream in = ftpClient.retrieveFileStream(new String(fileName.getBytes(fileEncoding), remoteEncoding));
byte[] bytes = new byte[1024];
int c;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
}
in.close();
out.close();
boolean isDo = ftpClient.completePendingCommand();
if (isDo) {
logger.info("[{}]文件下载完毕", fileName);
count++;
} else {
logger.info("[{}]文件下载失败", fileName);
}
} else {
OutputStream out = new FileOutputStream(f);
InputStream in = ftpClient.retrieveFileStream(new String(fileName.getBytes(fileEncoding), remoteEncoding));
byte[] bytes = new byte[1024];
int c;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
}
in.close();
out.close();
boolean upNewStatus = ftpClient.completePendingCommand();
if (upNewStatus) {
logger.info("[{}]文件下载完毕", fileName);
count++;
} else {
logger.info("[{}]文件下载失败", fileName);
}
}
return count;
} catch (IOException e) {
logger.error(e.getMessage());
return 0;
} finally {
closeServer();
}
}
/**
* Description: 向FTP服务器上传文件
* @param remotePath FTP服务器保存目录
* @param filename 上传到FTP服务器上的文件名
* @param f 输入流
* @return 成功返回true,否则返回false
*/
public boolean uploadFile(String remotePath, String filename, File f) {
boolean success = false;
int reply = ftpClient.getReplyCode();
try {
ftpClient.enterLocalPassiveMode();
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
}
if (!ftpClient.changeWorkingDirectory(remotePath)) {// 如果不能进入dir下,说明此目录不存在!
if (!ftpClient.makeDirectory(remotePath)) {
logger.info("创建文件目录【" + remotePath + "】 失败!");
}
}
ftpClient.changeWorkingDirectory(remotePath);
// 本地存在文件
InputStream input = new FileInputStream(f);
ftpClient.storeFile(filename, input);
input.close();
success = true;
} catch (IOException e) {
success =false ;
logger.error(e.getMessage());
} finally {
closeServer();
}
return success;
}
/**
* @param args
* @throws java.text.ParseException
*/
public static void main(String[] args) throws ParseException {
//FtpUtils ftp = new FtpUtils("10.211.1.111", 21, "bangfubao-front1", "bangfubao");
//int count = ftp.downAllFile("49261000","UTF-8","UTF-8","49261000");
//int count = ftp.downAllFiles("49261000", "49261000", "UTF-8", "iso-8859-1");
//System.out.println(count);
//ftp.closeServer();
//List<String> list = ftp.getFileList("49261000");
//System.out.println(list.toString());
}
}