import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/***
* @Description 描述
* @classname FtpUtil
* @Date 2021/5/28 10:04
*/
@Slf4j
@Component
public class FtpUtil {
private static Long userSizes = 0L;
private final static String DEFAULT_ENCODING = "ISO-8859-1";
@Autowired
private FtpClientFactory ftpClientFactoryPools;
private static FtpClientFactory ftpClientFactory;
@PostConstruct
public void init() {
ftpClientFactory = ftpClientFactoryPools;
}
/**
* 删除文件
*
* @param fileName
* @return
* @throws IOException
*/
public static boolean deleteFile(String fileName) throws IOException {
FTPClient ftpClient = null;
boolean result = false;
try {
ftpClient = ftpClientFactory.makeFtpClient();
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClientFactory.destroyClient(ftpClient);
return result;
}
result = ftpClient.deleteFile(new String(fileName.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING));
} catch (Exception e) {
log.error(e.toString());
} finally {
ftpClientFactory.destroyClient(ftpClient);
}
return result;
}
/**
* 创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
*
* @param remote
* @return
* @throws IOException
* @date 创建时间:2017年6月22日 上午11:51:33
*/
public static BaseResp CreateDirecroty(String remote, String workPath)
throws IOException {
BaseResp baseResp = null;
FTPClient ftp = null;
try {
ftp = ftpClientFactory.makeFtpClient();
int reply;
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClientFactory.destroyClient(ftp);
}
if (!ftp.changeWorkingDirectory(new String(workPath.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
return baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
}
String[] dir = remote.split("/");
List<String> list = new ArrayList<>();
for (int i = 0; i < dir.length; i++) {
if (StringUtils.isNotEmpty(dir[i])) {
list.add(dir[i]);
}
}
for (String li : list) {
String subDirectory = new String(li.getBytes("UTF-8"), DEFAULT_ENCODING);
if (!ftp.changeWorkingDirectory(subDirectory)) {
log.info("目录不存在,创建目录");
ftp.makeDirectory(subDirectory);
ftp.changeWorkingDirectory(subDirectory);
} else {
ftp.changeWorkingDirectory(subDirectory);
baseResp = new BaseResp(CommonEnum.FILE_EXITIS);
log.info("目录已存在", subDirectory);
continue;
}
}
} catch (Exception e) {
ftpClientFactory.destroyClient(ftp);
log.error(e.toString());
return baseResp = new BaseResp(CommonEnum.FAIL);
}
return baseResp = new BaseResp(CommonEnum.SUCCESS);
}
/***
* 删除FTP目录
* 目录路径只能从最后一个往前面删 比如:/tools/test/test 删除的话是先最后一个,如果要删除全部纪要循环
*/
public static boolean deleteDir(String path) {
boolean flag = false;
FTPClient ftp = null;
try {
ftp = ftpClientFactory.makeFtpClient();
//先判断要删除的文件存不存在
if (!ftp.changeWorkingDirectory(path)) {
return flag;
}
log.info("当前工作目录" + ftp.printWorkingDirectory());
FTPFile[] file = ftp.listFiles(path);
if (file != null) {
log.info("该文件夹下存在文件");
return false;
}
while (true) {
//删除当前文件夹 path="/tools/test/test1
if (ftp.removeDirectory(path)) {
//回到父级文件 /tools/test
ftp.changeToParentDirectory();
//得到当前文件夹路径 /tools/test
path = ftp.printWorkingDirectory();
log.info("上级文件夹路径:" + ftp.changeToParentDirectory());
log.info("当前工作目录" + ftp.printWorkingDirectory());
if (path.equals("/tools")) {
flag = true;
break;
}
}
}
} catch (Exception e) {
log.error("FTP操作出错,请联系管理员", e.toString());
} finally {
ftpClientFactory.destroyClient(ftp);
}
return flag;
}
/**
* 获取用户FPT目录的文件列表信息
*
* @param path
* @return
*/
public static BaseResp getFtpFileList(String path, String workPath) {
BaseResp resp = null;
String userPath = path;
List<FileEntityDto> list = new ArrayList<>();
FTPClient ftp = null;
try {
ftp = ftpClientFactory.makeFtpClient();
ftp.setControlEncoding("UTF-8");
path = workPath + path;
path = new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
if (!ftp.changeWorkingDirectory(path)) {
resp = new BaseResp(CommonEnum.FILE_NO_EXITIS);
resp.setMessage("该文件夹不存在,请检查!");
return resp;
}
Long sumSzie = 0L;
FTPFile[] ftpFile = ftp.listFiles(path);
for (FTPFile file : ftpFile) {
FileEntityDto fileEntityDto = new FileEntityDto();
//如果是文件夹 获取其里全部文件 得到文件大小 统计文件夹占用空间大小
if (file.getType() == 1) {
FTPFile[] files = ftp.listFiles(path + "/" + file.getName());
if (ObjectUtils.isNotEmpty(files)) {
for (FTPFile fi : files) {
sumSzie += fi.getSize();
}
}
}
fileEntityDto.setFilePath(userPath);
fileEntityDto.setFileName(file.getName());
fileEntityDto.setFileType(String.valueOf(file.getType()));
if (file.getType() != 1) {
fileEntityDto.setFileSize(GetFileSize(file));
} else {
fileEntityDto.setFileSize(GetFileSizes(sumSzie));
}
fileEntityDto.setUpDate(DateUtils.formatDate(file.getTimestamp().getTime(), "yyyy-MM-dd HH:mm:ss"));
list.add(fileEntityDto);
}
} catch (Exception e) {
log.error(e.toString());
} finally {
ftpClientFactory.destroyClient(ftp);
}
resp = new BaseResp(CommonEnum.SUCCESS, list);
return resp;
}
/**
* 获取用户FPT已用空间大小
*
* @param path
* @return
*/
public static BaseResp getFtpFileSize(String path) {
BaseResp resp = null;
Long userSize = 0L;
FTPClient ftp = null;
TreeVo vo = new TreeVo("tools", 0L);
try {
ftp = ftpClientFactory.makeFtpClient();
ftp.setControlEncoding("UTF-8");
if (!ftp.changeWorkingDirectory(path)) {
resp = new BaseResp(CommonEnum.FILE_NO_EXITIS);
resp.setMessage("该文件夹不存在,请检查!");
return resp;
}
String dirPath = path;
FTPFile[] ftpFile = null;
List<String> dirName = new ArrayList<>();
ftpFile = ftp.listFiles(dirPath);
vo = recursionTree(ftpFile, ftp, vo);
List<TreeVo> children = vo.getChildren();
log.info("userSzies={}", vo.getSize());
} catch (Exception e) {
log.error(Atom.ERROR_MSG, "ftp连接出错:" + e.getMessage());
} finally {
ftpClientFactory.destroyClient(ftp);
}
resp = new BaseResp(CommonEnum.SUCCESS, vo.getSize());
return resp;
}
/***
* 循环进入目录获取size
* @param ftp
* @param dirName
* @param path 原始路径
* @return
*/
public static boolean getSize(FTPClient ftp, String path, List<String> dirName) {
log.info("根目录地址:" + path);
Long size = 0L;
List<String> fileList = new ArrayList<>();
try {
//进入目录
Iterator it = dirName.iterator();
while (it.hasNext()) {
String newDirPath = null;
String name = it.next().toString();
String paths = path + "/" + name;
log.info("遍历文件名得到的新目录:" + paths);
if (ftp.changeWorkingDirectory(paths)) {
FTPFile[] files = ftp.listFiles(paths);
if (files.length != 0) {
//再去里面查!给我查!
for (FTPFile file : files) {
if (file.getType() == 1) {
fileList.add(file.getName());
newDirPath = paths;
log.info("文件夹下还存在文件夹的地址:" + newDirPath);
getSize(ftp, newDirPath, fileList);
} else {
//不记录文件夹的Size
size += file.getSize();
userSizes = size;
log.info("size={}", userSizes);
}
}
}
} else {
return false;
}
}
} catch (IOException e) {
log.error(e.toString());
}
return true;
}
//重命名文件或者文件夹 需要路径,需要原名称和新名称,新名称是文件 则要加后缀
public static boolean reName(String path, String from, String to) {
FTPClient ftp = null;
try {
ftp = ftpClientFactory.makeFtpClient();
//进入path
if (!ftp.changeWorkingDirectory(new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
return false;
}
//获取最后一个.的位置
int lastIndexOf = from.lastIndexOf(".");
String newFileNma = to;
//-1说明是文件夹没有后缀
// if (lastIndexOf != -1) {
// String suffix = from.substring(lastIndexOf);
// newFileNma = to + suffix;
// } else newFileNma = to;
if (!ftp.rename(from, new String(newFileNma.getBytes("UTF-8"),
DEFAULT_ENCODING))) {
return false;
}
} catch (Exception e) {
log.error(e.toString());
} finally {
ftpClientFactory.destroyClient(ftp);
}
return true;
}
/**
* 上传文件到FTP 支持中文
*
* @param inputStream
* @param path
* @param fileNmae
* @return
*/
public static BaseResp upload(InputStream inputStream, String path, String fileNmae) {
BaseResp baseResp = null;
log.info("上传文件开始");
log.info("path={]", path);
FTPClient ftpClient = null;
try {
ftpClient = ftpClientFactory.makeFtpClient();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setDataTimeout(60000);
if (!ftpClient.changeWorkingDirectory(new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
return baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
}
try {
ftpClient.storeFile(new String(fileNmae.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING), inputStream);
String filePath = new String(path.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
String file = new String(fileNmae.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
FTPFile[] files = ftpClient.listFiles(filePath + "/" + file);
if (files.length > 0) {
baseResp = new BaseResp(CommonEnum.SUCCESS);
baseResp.setMessage("文件上传成功!");
} else {
baseResp = new BaseResp(CommonEnum.UPLOAD_FILE_ERROR);
baseResp.setMessage("文件上传失败!");
}
} catch (IOException e) {
log.error(e.toString());
}
} catch (Exception e) {
log.error(e.toString());
} finally {
ftpClientFactory.destroyClient(ftpClient);
}
return baseResp;
}
/**
* FTP下载单个文件测试
*/
public static BaseResp downloadFtpFile(
String ftpPath,
String uploadFileName,
HttpServletResponse response) {
boolean bn = false;
FTPClient ftpClient = null;
try {
ftpClient = ftpClientFactory.makeFtpClient();
// 设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("applicatoin/octet-stream");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
String filesName = URLEncoder.encode(uploadFileName, StandardCharsets.UTF_8);
filesName = URLEncoder.encode(uploadFileName, "UTF-8");
response.setHeader(
"Content-Disposition",
"attachment;filename=" + java.net.URLDecoder.decode(filesName, "UTF-8"));
response.setHeader("Cache-Control", "no-cache");
ftpClient.setControlEncoding("UTF-8");
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
int reply = ftpClient.getReplyCode();
// 切换到ftp的服务器路径
if (!ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING))) {
return new BaseResp(CommonEnum.FILE_NO_EXITIS);
}
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new IOException("failed to connect to the FTP Server");
}
// 此句代码适用Linux的FTP服务器
String newPath = new String(uploadFileName.getBytes("UTF-8"), DEFAULT_ENCODING);
OutputStream out = response.getOutputStream();
InputStream in = ftpClient.retrieveFileStream(newPath);
BufferedInputStream bis = new BufferedInputStream(in);
byte[] buf = new byte[1024];
int len = 0;
while ((len = bis.read(buf)) > 0) {
out.write(buf, 0, len);
}
bis.close();
in.close();
out.flush();
return new BaseResp(CommonEnum.SUCCESS);
} catch (FTPConnectionClosedException e) {
log.error("ftp连接被关闭!ERROR={}", e.getMessage());
throw new BizException(-1, e.getMessage());
} catch (Exception e) {
log.error("ERR : upload file " + uploadFileName + " from ftp : failed!", e.getMessage());
throw new BizException(-1, e.getMessage());
}
}
public static String GetFileSize(FTPFile file) {
String size = "";
long fileS = file.getSize();
DecimalFormat df = new DecimalFormat("#.00");
if (fileS < 1024) {
size = df.format((double) fileS) + "BT";
} else if (fileS < 1048576) {
size = df.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
size = df.format((double) fileS / 1048576) + "MB";
} else {
size = df.format((double) fileS / 1073741824) + "GB";
}
return size;
}
//转换占用内存
public static String GetFileSizes(Long sumSzie) {
String size = "";
long fileS = sumSzie;
DecimalFormat df = new DecimalFormat("#.00");
if (fileS < 1024) {
size = df.format((double) fileS) + "BT";
} else if (fileS < 1048576) {
size = df.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
size = df.format((double) fileS / 1048576) + "MB";
} else {
size = df.format((double) fileS / 1073741824) + "GB";
}
return size;
}
/* public static void getst(FTPClient ftpClient, String path) throws IOException {
try {
ftpClient = ftpClientFactory.makeFtpClient();
// 如果ftp连接成功,需要验证路径是否存在
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
ftpClient.setControlEncoding("UTF-8");
// 获取根目录文件
FTPFile[] files = ftpClient.listFiles(path);
// 创建根节点
TreeVo root = new TreeVo("tools", 0L);
if (files.length > 0) {
try {
recursionTree(files, ftpClient, root);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (SocketException e) {
} catch (IOException e) {
e.printStackTrace();
log.info("FTP的端口错误,请正确配置。");
} catch (Exception e) {
e.printStackTrace();
log.info("查询数据失败。");
}
}*/
/**
* 递归获取ftp文件目录树
*
* @param files
* @param ftpClient
* @param pTree
* @return
* @throws IOException
*/
public static TreeVo recursionTree(FTPFile[] files, FTPClient ftpClient, TreeVo pTree) throws IOException {
Long size = 0L;
for (FTPFile file : files) {
if (file.isDirectory()) {
// new String(file.getName().getBytes("UTF-8"),"iso-8859-1")为了将目录名的编码转成FTPClient需要的编码,否则切换目录会失败。
boolean flag = ftpClient.changeWorkingDirectory(new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
files = ftpClient.listFiles();
if (files.length > 0) {
pTree.getChildren().add(recursionTree(files, ftpClient, new TreeVo(file.getName(), file.getSize())));
} else {
pTree.getChildren().add(new TreeVo(file.getName(), file.getSize()));
}
} else {
log.info(file.getName() + ":文件大小为:" + file.getSize());
size += file.getSize();
log.info("size={}", size.toString());
userSizes += file.getSize();
pTree.setSize(size);
pTree.getChildren().add(new TreeVo(file.getName(), file.getSize()));
}
}
// 子文件夹遍历完成后返回上级目录
ftpClient.changeToParentDirectory();
return pTree;
}
//视频截图 并生成文件夹存放文件
public static BaseResp screenshots(String seconds, List<String> fileName, String path, String ffmpegUrl) {
BaseResp baseResp;
log.info("进入FTP处理视频截图");
log.info("fileName={}", ToStringBuilder.reflectionToString(fileName, ToStringStyle.MULTI_LINE_STYLE));
FTPClient ftpClient = null;
try {
ftpClient = ftpClientFactory.makeFtpClient();
ftpClient.setControlEncoding("UTF-8");
path = new String(path.getBytes("UTF-8"), DEFAULT_ENCODING);
//进入路径
if (ftpClient.changeWorkingDirectory(path)) {
Iterator it = fileName.iterator();
while (it.hasNext()) {
String videoName = (String) it.next();
videoName = new String(videoName.getBytes(StandardCharsets.UTF_8), DEFAULT_ENCODING);
FTPFile[] file = ftpClient.listFiles(path + "/" + videoName);
if (file.length != 0) {
for (FTPFile ftpFile : file) {
String absolutePath = videoName;
String name = ftpFile.getName();
String oldDir = absolutePath;
String time = DateUtil.getTimeStrBySecond(Integer.valueOf(seconds));
String outName = path + "/" + System.currentTimeMillis() + "Screenshots";
CreateDirecroty(outName, path);
String size = "1920x1080";
FfmpegUtils.covPic(oldDir, time, outName, size);
}
} else {
continue;
}
}
} else {
baseResp = new BaseResp(CommonEnum.DIR_IS_NOT_EXITIS);
return baseResp;
}
} catch (Exception e) {
log.error(e.toString());
} finally {
ftpClientFactory.destroyClient(ftpClient);
}
return null;
}
}
FTP常用操作 做个记录
最新推荐文章于 2022-10-02 18:21:51 发布