package cn.huge.module.file.utils; import cn.huge.base.common.exception.MethodException; import cn.huge.module.constant.BaseConsts; import cn.huge.module.file.config.FtpFileConfig; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPClientConfig; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.springframework.stereotype.Component; import java.io.IOException; import java.io.InputStream; /** * @title: ftp配工具类 * @description: ftp配工具类 * @company: hugeinfo * @author: liyj * @time: 2021-11-05 16:51:48 * @version: 1.0.0 */ @Slf4j @Component public class FtpUtils { /** * 上传附件. * @param path 服务器存储路径(/home/ftp/huge-dyh) * @param fileName 文件名(1.jpg) * @param inputStream 文件流 */ public void upload(String path, String fileName, InputStream inputStream) { FTPClient ftpClient = new FTPClient(); try { if (connect(ftpClient)) { // 检查文件目录是否存在,不存在创建目录 if (this.checkDir(ftpClient, path)) { // 检查是否上传成功 if (storeFile(ftpClient, fileName, inputStream)) { disconnect(ftpClient); }else{ disconnect(ftpClient); throw new MethodException("连接ftp成功,上传文件失败!"); } }else{ disconnect(ftpClient); throw new MethodException("连接ftp成功,检查文件目录不存在!"); } }else{ disconnect(ftpClient); throw new MethodException("连接ftp失败!"); } } catch (Exception e) { disconnect(ftpClient); log.error("方法[FtpUtils.upload]调用异常:"+e, e); throw new MethodException("FtpUtils.upload", e); } } /** * 从文件服务器获取文件流. * @param filePath 文件存储完整路径(/home/ftp/huge-dyh/1.jpg) * @return {@link InputStream} * @throws IOException */ public InputStream retrieveFileStream(String filePath) { if (StringUtils.isBlank(filePath)) { throw new MethodException("文件路径为空!"); } log.info("读取文件路径[filePath]值" + filePath); FTPClient ftpClient = new FTPClient(); try { if (connect(ftpClient)) { filePath = new String(filePath.getBytes("UTF-8"), "iso-8859-1"); InputStream inputStream = ftpClient.retrieveFileStream(filePath); disconnect(ftpClient); return inputStream; }else{ disconnect(ftpClient); throw new MethodException("连接ftp失败!"); } } catch (Exception e) { disconnect(ftpClient); log.error("方法[FtpUtils.retrieveFileStream]调用异常:"+e, e); throw new MethodException("FtpUtils.retrieveFileStream", e); } } /** * 删除文件 * @param filePath 文件存储完整路径(/home/ftp/huge-dyh/1.jpg) */ public void deleteFile(String filePath) { try{ String workingPath = filePath.substring(0, filePath.lastIndexOf("/")); String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); deleteFile(workingPath, fileName); }catch (Exception e){ log.error("方法[FtpUtils.deleteFile]调用异常:"+e, e); throw new MethodException("FtpUtils.deleteFile", e); } } /** * ftp操作-连接ftp * @param ftpClient ftp工具 * @return boolean */ private boolean connect(FTPClient ftpClient) { boolean flag = false; try { // 远程ftp需要加上,允许被动连接 ftpClient.enterLocalPassiveMode(); FTPClientConfig clientConfig = new FTPClientConfig(); clientConfig.setLenientFutureDates(true); ftpClient.configure(clientConfig); // 连接ftp log.info("连接ftp"+FtpFileConfig.getHostname(), FtpFileConfig.getPort()); ftpClient.connect(FtpFileConfig.getHostname(), FtpFileConfig.getPort()); if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { log.info("连接ftp成功!"); boolean login = ftpClient.login(FtpFileConfig.getUsername(), FtpFileConfig.getPassword()); log.info("登录ftp成功:{}",login); if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { // 设置以二进制方式传输 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 设置UTF-8编码 ftpClient.setControlEncoding("UTF-8"); //设置传输方式为流方式 ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE); // 设置缓冲区大小 ftpClient.setBufferSize(1024); log.info("登录ftp成功!"); flag = true; } else { log.error("登录ftp失败,可能用户名或密码错误!"); } }else{ log.error("连接ftp失败,可能ip或端口错误!"); } return flag; } catch (IOException e) { log.error("方法[FtpUtils.connect]调用异常:"+e, e); throw new MethodException("FtpUtils.connect", e); } } /** * ftp操作-检查文件目录不存在时,创建目录 * @param ftpClient ftp工具 * @param path 服务器存储路径(/home/ftp/huge-dyh) * @return String */ public Boolean checkDir(FTPClient ftpClient, String path){ try{ log.info("上传路径为:" + path); Boolean flag = false; if (!ftpClient.changeWorkingDirectory(path)) { StringBuffer rootPath = new StringBuffer(); rootPath.append(FtpFileConfig.getRootdir()); // 创建文件目录 path = path.replace(FtpFileConfig.getRootdir() + BaseConsts.SLANT, ""); String[] paths = path.split(BaseConsts.SLANT); for (String filePath: paths){ if (StringUtils.isBlank(filePath)){ continue; }else{ rootPath.append(BaseConsts.SLANT); rootPath.append(filePath); if (!ftpClient.changeWorkingDirectory(rootPath.toString())){ ftpClient.makeDirectory(rootPath.toString()); } } } // 严谨一点,再检查文件目录是否存在 if (ftpClient.changeWorkingDirectory(rootPath.toString())) { flag = true; } }else{ flag = true; } return flag; }catch (Exception e){ log.error("方法[FtpUtils.makeDir]调用异常:"+e, e); throw new MethodException("FtpUtils.makeDir", e); } } /** * ftp操作-上传文件到ftp * @param ftpClient ftp工具 * @param fileName 文件名称(1.jpg) * @param fileInputStream 文件流 * @return boolean */ private boolean storeFile(FTPClient ftpClient, String fileName, InputStream fileInputStream) { boolean flag = false; try { fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); log.info("上传文件名为:" + fileName); boolean b = ftpClient.storeFile(fileName, fileInputStream); String status = ftpClient.getStatus(); log.info("上传状态:{},{}" ,b, status); int reply = ftpClient.getReplyCode(); if (FTPReply.isPositiveCompletion(reply)) { flag = true; log.info("上传文件成功!"); }else{ log.error("上传文件失败!请求响应码[reply]值为:" + reply); } fileInputStream.close(); return flag; } catch (IOException e) { log.error("方法[FtpUtils.storeFile]调用异常:"+e, e); throw new MethodException("FtpUtils.storeFile", e); } } /** * ftp操作-删除附件. * @param path 服务器存储路径(/home/ftp/huge-dyh) * @param fileName 附件名称(1.jpg) */ public void deleteFile(String path, String fileName) { FTPClient ftpClient = new FTPClient(); try{ connect(ftpClient); if (ftpClient.changeWorkingDirectory(path)) { // 删除文件 ftpClient.dele(fileName); disconnect(ftpClient); }else { disconnect(ftpClient); throw new MethodException("文件路径不存在!"); } }catch (Exception e){ disconnect(ftpClient); log.error("方法[FtpUtils.deleteFile]调用异常:"+e, e); throw new MethodException("FtpUtils.deleteFile", e); } } /** * ftp操作-断开ftp连接. * @param ftpClient ftp工具 */ private void disconnect(FTPClient ftpClient) { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException e) { log.error("方法[FtpUtils.disconnect]调用异常:"+e, e); throw new MethodException("FtpUtils.disconnect", e); } } } }