package com.dc.common.utils;
import com.dc.common.config.ThreadContextHolderConfig;
import com.dc.common.exception.CustomException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
* @author 肘劉祁
*/
@Slf4j
@Component
public class FtpUtil {
/**
* 服务器ip地址
*/
@Value("${ftp.ip}")
private String ip;
/**
* 服务器用户名称
*/
@Value("${ftp.username}")
private String username;
/**
* 服务器用户密码
*/
@Value("${ftp.password}")
private String password;
/**
* FTP客户端
*/
private FTPClient ftpClient;
/**
* 本地编码
*/
private static String LOCAL_CHARSET = "GBK";
/**
* 服务器默认编号
*/
private static String SERVER_CHARSET = FTPClient.DEFAULT_CONTROL_ENCODING;
/**
* 连接服务器
*
* @return 连接结果
*/
private boolean connectService() throws IOException {
//初始化客户端对象
ftpClient = new FTPClient();
//连接FTP服务器
ftpClient.connect(ip);
//登录
ftpClient.login(username, password);
//连接状态值
int reply = ftpClient.getReplyCode();
//判断连接状态
if (!FTPReply.isPositiveCompletion(reply)) {
//关闭连接
ftpClient.disconnect();
return false;
}
// 设置缓存区
ftpClient.setBufferSize(1024);
// 开通一个端口来传输数据
ftpClient.enterLocalPassiveMode();
//判断服务器是否支持UTF-8
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF-8", "ON"))) {
LOCAL_CHARSET = "UTF-8";
}
//配置WINDOWS可查看文件
ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_NT));
//上传格式
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
log.info("FTP连接服务器成功");
return true;
}
/**
* 上传文件
* @param multipartFile 上传对象
* @return 上传结果
*/
public boolean uploadFile(MultipartFile multipartFile, String filePath) {
try {
//连接服务器
if (!connectService()) {
return false;
}
//获取文件路径进入目录
intoFolder(toString(filePath.substring(0,filePath.lastIndexOf("/") + 1)));
//执行上传操作并判断上传状态
if (!ftpClient.storeFile(toString(multipartFile.getOriginalFilename()), multipartFile.getInputStream())) {
return false;
}
} catch (IOException e) {
e.printStackTrace();
throw new CustomException("上传失败,请联系管理员");
} finally {
close(ftpClient);
}
return true;
}
/**
* 创建目录并进入目录
* @param filePath 目标目录
* @throws IOException 异常信息
*/
public void intoFolder(String filePath) throws IOException {
//目录列表
String[] split =filePath.split("/");
//遍历目录
for (int i = 0; i < split.length; i++) {
//非空判断
if (StringUtils.isBlank(split[i])) {
//判断是否为刚开始
if (i == 0) {
//进入/上传目录
ftpClient.changeWorkingDirectory("/");
}
continue;
}
//进入"+split[i]+"上传目录
if (!ftpClient.changeWorkingDirectory(split[i])) {
//split[i]+"目录不存在===>创建目录"
if (!ftpClient.makeDirectory(split[i])) {
//split[i]+"目录创建失败"
} else {
//"进入"+split[i]+"上传目录"
ftpClient.changeWorkingDirectory(split[i]);
}
}
}
}
/**
* 下载文件
* @param filePath 文件路径
* @return 文件流
*/
public byte[] downloadFile(String filePath) {
try {
//连接服务器
if (!connectService()) {
return null;
}
//判断是否有这个目录
if (!ftpClient.changeWorkingDirectory(toString(filePath.substring(0, filePath.lastIndexOf("/"))))) {
return null;
}
//获取目录下的文件
FTPFile[] fs = ftpClient.listFiles();
//文件名称
String fileName =toString(filePath.substring(filePath.lastIndexOf("/") + 1));
//遍历所有的文件列表
for (FTPFile file : fs) {
//匹配文件名称
if (file.getName().contains(fileName)) {
//返回数据
return IOUtils.toByteArray(ftpClient.retrieveFileStream(fileName));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
close(ftpClient);
}
return null;
}
/**
* 关闭FTP
* @param ftpClient 客户端
*/
public static void close(FTPClient ftpClient){
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 删除文件夹
*
* @param filePath 文件夹路径
* @return 操作结果
*/
public Boolean deleteDirectory(String filePath) {
try {
//获取目录下的文件
FTPFile[] fs = ftpClient.listFiles(toString(filePath));
//遍历所有的文件列表
for (FTPFile file : fs) {
//文件名称
String name =file.getName().substring(file.getName().lastIndexOf(" ")+1);
String filename = toString(filePath + "/" + name);
//判断是否是文件夹
if (!name.contains(".")) {
//递归操作
if (!deleteDirectory(filename)) {
return false;
}
} else {
//删除文件操作
if (!ftpClient.deleteFile(toString(filename))) {
return false;
}
}
}
//切换目录
ftpClient.changeWorkingDirectory(toString(filePath));
//执行删除目录
if (!ftpClient.removeDirectory(toString(filePath))) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* 删除操作
*
* @param filePath 删除目录
* @return 操作结果
*/
public Boolean deleteAllFile(String filePath) {
try {
//连接服务器
if (!connectService()) {
return false;
}
//删除操作
return deleteDirectory(filePath);
}catch (Exception e){
e.printStackTrace();
}finally {
close(ftpClient);
}
return false;
}
/**
* 移动文件
* @param remotePath 文件存储位置
* @param path 文件相对位置
* @param id 用户编号
* @return 操作结果
*/
public Boolean moveFile(String remotePath,String path,Integer id) {
try {
//连接服务器
if (!connectService()) {
return false;
}
//开始路径
String formPath = toString(remotePath + id + "/" + path.substring(0, path.lastIndexOf("/")));
//到达路径
String toPath = toString(remotePath + path.substring(0, path.lastIndexOf("/")));
//进入目录
intoFolder(toPath);
//判断有没有这个路径
if (!ftpClient.changeWorkingDirectory(formPath)) {
return false;
}
//获取目录下的文件
FTPFile[] fs = ftpClient.listFiles();
//文件名称
String fileName = toString(path.substring(path.lastIndexOf("/") + 1));
//遍历所有的文件列表
for (FTPFile file : fs) {
//匹配文件名称
if (file.getName().contains(fileName)) {
return ftpClient.rename(fileName, toPath +"/"+ fileName);
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
close(ftpClient);
}
return false;
}
/**
* 字符串转换
* @param name 需要转换的字符串
* @return 转换后的字符串
* @throws UnsupportedEncodingException 异常信息
*/
private String toString(String name) throws UnsupportedEncodingException {
return new String(name.getBytes(LOCAL_CHARSET),SERVER_CHARSET);
}
}
<!--FTP-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>