package com.aa.app.utils;
import com.aa.framework.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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 java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
public class FtpUtil {
private static Log log = LogFactory.getLog(FtpUtil.class);
/**
* 维护FTPClient实例
*/
private final static LinkedBlockingQueue<FTPClient> FTP_CLIENT_QUEUE = new LinkedBlockingQueue<>();
/***
* @下载文件夹 递归下载文件夹下所有的文件
* @param localDirectoryPath本地地址
* @param remoteDirectory 远程文件夹
* localDirectoryPath 文件下载到本地那个路径
* remoteDirectory FTP远程路径(需要下载的文件路径)
* downMap FTP IP、户名、密码、端口、信息
* bpmCodeList 个人业务需要,可忽略
* */
public static boolean downLoadDirectory(String localDirectoryPath, String remoteDirectory, Integer localPassiveMode, List<String> bpmCodeList, Map<String,String> downMap) throws Exception {
FTPClient ftpClient = null;
try {
FtpConfig ftpConfig = new FtpConfig().setUserName(downMap.get("downUserName")).setPassword(downMap.get("downPassword"))
.setIp(downMap.get("downUrl")).setPort(Integer.valueOf(downMap.get("downFtpPort")));
//登录ftp
ftpClient = connectClient(ftpConfig);
boolean flag1 = ftpClient.changeWorkingDirectory(remoteDirectory);
if(!flag1){
log.error("没有找到" + remoteDirectory + "---该路径");
return false;
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("GBK");
// 如果FTP支持UTF-8编码,则设置未UTF-8
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
ftpClient.setControlEncoding("UTF-8");
}else{
log.info("sendCommand不支持:sendCommand");
}
String fileName = new File(remoteDirectory).getName();
localDirectoryPath = localDirectoryPath + fileName + "//";
String localDirectoryPathTmp = localDirectoryPath;
log.info("文件下载到的路径:" + localDirectoryPath);
new File(localDirectoryPath).mkdirs();
if(1 == localPassiveMode){
ftpClient.enterLocalPassiveMode();//被动模式
}
FTPFile[] allFile = ftpClient.listFiles();
if(allFile == null || allFile.length ==0){
log.info("远程文件夹不存在或者里面没有文件:" + remoteDirectory);
}
for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
if(allFile[currentFile].getName().startsWith(".")){
log.info("遍历到无用文件,名称为:" + allFile[currentFile].getName());
continue;
}
//如果不是文件夹则下载
if (!allFile[currentFile].isDirectory()) {
log.info("原文件名称:"+allFile[currentFile].getName());
downloadTwo(ftpClient,remoteDirectory,allFile[currentFile].getName(),localDirectoryPath + allFile[currentFile].getName(), localPassiveMode);
localDirectoryPath = localDirectoryPathTmp;
}
}
//如果是文件夹则继续执行找文件
for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
if(allFile[currentFile].getName().startsWith(".")){
log.info("遍历到无用文件夹,名称为:" + allFile[currentFile].getName());
continue;
}
if (allFile[currentFile].isDirectory()) {
log.info("是文件夹名字:" + allFile[currentFile].getName());
//保存文件夹名字
bpmCodeList.add(allFile[currentFile].getName());
String strremoteDirectoryPath = remoteDirectory + "/"+ allFile[currentFile].getName();
downLoadDirectory(localDirectoryPath,strremoteDirectoryPath,localPassiveMode,bpmCodeList,downMap);
}
}
}catch (Exception e) {
log.error("下载文件夹失败" + ExceptionUtils.getFullStackTrace(e));
log.info("下载文件夹失败");
return false;
}finally {
try {
// 退出FTP
ftpClient.logout();
// 归还对象
ftpClient.disconnect();
} catch (Exception e) {
throw new Exception("关闭FTP连接发生异常!", e);
}
}
return true;
}
/**
* 下载文件
*
* @param ftpConfig
* 配置
* @param remotePath
* 远程目录
* @param fileName
* 文件名
* @param localPath
* 本地目录+本地文件名
*
* @return 是否下载成功
*/
private static boolean downloadTwo(FTPClient ftpClient, String remotePath,
String fileName, String localPath,Integer localPassiveMode) throws Exception {
OutputStream outputStream = null;
try {
ftpClient.changeWorkingDirectory(remotePath);
File file = new File(localPath);
if (!file.getParentFile().exists()) {
boolean mkdirsResult = file.getParentFile().mkdirs();
if (!mkdirsResult) {
throw new Exception("创建目录失败");
}
}
if (!file.exists()) {
boolean createFileResult = file.createNewFile();
if (!createFileResult) {
throw new Exception("创建文件失败");
}
}
if(1 == localPassiveMode){
ftpClient.enterLocalPassiveMode();//被动模式
}
outputStream = new FileOutputStream(file);
// 文件名称用UTF-8编码 不然文件名称中文乱码
boolean result1 = ftpClient.retrieveFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"), outputStream);
outputStream.flush();
log.info("下载成功,远程文件夹:" + remotePath + ",本地文件夹路径:" + localPath + ",文件名称"+fileName);
} catch (Exception e) {
log.error("下载失败" + ExceptionUtils.getFullStackTrace(e));
throw new Exception(e);
} finally {
try {
outputStream.close();
} catch (Exception e1) {
log.error(e1.getMessage(), e1);
}
}
return true;
}
/***
* @上传文件夹 将本地文件夹下所有文件上传到FTP
* @param localDirectory
* 当地文件夹
* @param remoteDirectoryPath
* Ftp 服务器路径 以目录"/"结束
* */
public static boolean uploadDirectory(String localDirectory,String remoteDirectoryPath,Integer localPassiveMode,Map<String,String> uploadMap,String bpmCode) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
String dateStr = format.format(new Date());
FTPClient ftpClient = null;
File src = new File(localDirectory);
try {
FtpConfig ftpConfig = new FtpConfig().setUserName(uploadMap.get("uploadUserName")).setPassword(uploadMap.get("uploadPassWord"))
.setIp(uploadMap.get("uploadUrl")).setPort(Integer.valueOf(uploadMap.get("uploadFtpPort")));
//登录ftp
ftpClient = FtpUtil.connectClient(ftpConfig);
ftpClient.changeWorkingDirectory(remoteDirectoryPath);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("GBK");
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
ftpClient.setControlEncoding("UTF-8");
}else{
log.info("sendCommand不支持:sendCommand");
}
if(1 == localPassiveMode){
ftpClient.enterLocalPassiveMode();//被动模式
}
// 创建一级目录
ftpClient.makeDirectory(remoteDirectoryPath);
ftpClient.changeWorkingDirectory(remoteDirectoryPath);
// 创建二级目录 --日期
remoteDirectoryPath = remoteDirectoryPath + "/" +dateStr;
ftpClient.makeDirectory(remoteDirectoryPath);
ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
// 创建三级目录 --bpm单号
remoteDirectoryPath = remoteDirectoryPath + "/" +bpmCode;
ftpClient.makeDirectory(remoteDirectoryPath);
ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
// remoteDirectoryPath = remoteDirectoryPath + src.getName() + "/";
// ftpClient.makeDirectory(remoteDirectoryPath);
// ftpClient.changeWorkingDirectory(remoteDirectoryPath.toString());
log.info("文件上传远程FTP路径 : " + remoteDirectoryPath);
File[] allFile = src.listFiles();
if(allFile == null || allFile.length ==0){
log.info("本地文件夹不存在或者里面没有文件:" + localDirectory);
}
for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
if (!allFile[currentFile].isDirectory()) {
String srcName = allFile[currentFile].getPath().toString();
uploadFile(ftpClient,new File(srcName), remoteDirectoryPath);
}
}
for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
if(allFile[currentFile].getName().startsWith(".")){
log.info("遍历到无用文件夹,名称为:" + allFile[currentFile].getName());
continue;
}
if (allFile[currentFile].isDirectory()) {
// 递归
uploadDirectory(allFile[currentFile].getPath().toString(),
remoteDirectoryPath,localPassiveMode,uploadMap,bpmCode);
}
}
}catch (IOException e) {
e.printStackTrace();
log.info(remoteDirectoryPath + "异常");
}finally {
try {
// 退出FTP
ftpClient.logout();
// 归还对象
ftpClient.disconnect();
} catch (Exception e) {
throw new Exception("关闭FTP连接发生异常!", e);
}
}
return true;
}
/***
* 上传Ftp文件
* @param localFile 当地文件
* @param romotUpLoadePath上传服务器路径 - 应该以/结束
* */
public static boolean uploadFile(FTPClient ftpClient,File localFile, String romotUpLoadePath) {
BufferedInputStream inStream = null;
boolean success = false;
try {
ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
inStream = new BufferedInputStream(new FileInputStream(localFile));
log.info(localFile.getName() + "开始上传.....");
log.info(new String(localFile.getName().getBytes("UTF-8"),"iso-8859-1") + "开始上传11");
log.info(new String(localFile.getName().getBytes("GBK"),"iso-8859-1") + "开始上传12");
// success = ftpClient.storeFile(localFile.getName(), inStream);
// log.info("1"+ success);
// success = ftpClient.storeFile(new String(localFile.getName().getBytes("GBK"),"iso-8859-1"), inStream);
// log.info("2"+ success);
success = ftpClient.storeFile(new String(localFile.getName().getBytes("UTF-8"),"iso-8859-1"), inStream);
log.info("3"+ success);
if (success == true) {
log.info(localFile.getName() + "上传成功");
return success;
}
}catch (FileNotFoundException e) {
e.printStackTrace();
log.error(localFile + "未找到");
}catch (IOException e) {
e.printStackTrace();
}finally {
if (inStream != null) {
try {
inStream.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
* 登录ftp
*
* @param ftpConfig
* 配置
* @return 是否登录成功
* @throws IOException
*/
public static FTPClient connectClient(FtpConfig ftpConfig)
throws Exception {
FTPClient ftpClient = getClient();
// 连接FTP服务器
ftpClient.connect(ftpConfig.ip, ftpConfig.port);
// 登录FTP
ftpClient.login(ftpConfig.userName, ftpConfig.password);
// 正常返回230登陆成功
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new Exception("连接ftp失败");
}
ftpClient.setControlEncoding("GBK");
return ftpClient;
}
/**
* 获取ftpClient对象
*
* @return 获取client对象
*/
private static FTPClient getClient() {
// FTPClient ftpClient = FTP_CLIENT_QUEUE.poll();
// if (ftpClient != null) {
// return ftpClient;
// }
return new FTPClient();
}
private static void offer(FTPClient ftpClient) {
FTP_CLIENT_QUEUE.offer(ftpClient);
}
/**
* 连接ftp配置
*/
public static class FtpConfig {
private String ip;
private int port;
private String userName;
private String password;
public FtpConfig setIp(String ip) {
this.ip = ip;
return this;
}
public FtpConfig setPort(int port) {
this.port = port;
return this;
}
public FtpConfig setUserName(String userName) {
this.userName = userName;
return this;
}
public FtpConfig setPassword(String password) {
this.password = password;
return this;
}
}
}
FTP上传下载,防止中文乱码,亲测可用
于 2023-06-20 14:20:43 首次发布