Java Ftp文件上传

tech2025-11-10  5

环境为springboot项目:

Maven依赖:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>

application.yml配置文件:

#ftp配置 ftp: userName: //账号 password: //密码 host: //192.168.1.000//地址 outPost: 192.168.1.000//地址 port: 21//端口 pathPrefix: transportation/ //上传文件路径 FtpUtils工具: package com.knd.common.utils; import com.knd.enums.FileTypeEnum; import lombok.extern.slf4j.Slf4j; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.SocketException; import java.util.*; /** * @Description: ftp工具类 */ @Slf4j @Component @ConfigurationProperties(prefix = "ftp")//读取配置文件的值 public class FtpUtils { public static String userName; public static String password; public static String host; public static String outPost; public static int port; public static String pathPrefix; public void setOutPost(String outPost) { FtpUtils.outPost = outPost; } public void setUserName(String userName) { FtpUtils.userName = userName; } public void setPassword(String password) { FtpUtils.password = password; } public void setHost(String host) { FtpUtils.host = host; } public void setPort(int port) { FtpUtils.port = port; } public void setPathPrefix(String pathPrefix) { FtpUtils.pathPrefix = pathPrefix; } /** * 获取FTPClient对象 * * @return */ public static FTPClient getFTPClient() { FTPClient ftpClient = new FTPClient(); try { ftpClient = new FTPClient(); ftpClient.connect(host, port);// 连接FTP服务器 ftpClient.login(userName, password);// 登陆FTP服务器 if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { log.error("未连接到FTP,,请正确配置。"); ftpClient.disconnect(); } else { log.info("FTP连接成功。"); } } catch (SocketException e) { e.printStackTrace(); log.error("FTP的IP地址可能错误,请正确配置。错误明细:" + e.getMessage()); } catch (IOException e) { e.printStackTrace(); log.error("FTP的端口错误,请正确配置。错误明细:" + e.getMessage()); } return ftpClient; } /** * 从FTP服务器下载文件 * * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa * @param localPath 下载到本地的位置 格式:H:/download * @param fileName 文件名称 */ public static void downloadFtpFile(String ftpPath, String localPath, String fileName) { FTPClient ftpClient = null; try { ftpClient = getFTPClient(); ftpClient.setControlEncoding("UTF-8"); // 中文支持 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); ftpClient.changeWorkingDirectory(ftpPath); File localFile = new File(localPath + File.separatorChar + fileName); OutputStream os = new FileOutputStream(localFile); ftpClient.retrieveFile(fileName, os); os.close(); ftpClient.logout(); } catch (FileNotFoundException e) { System.out.println("没有找到" + ftpPath + "文件"); e.printStackTrace(); } catch (SocketException e) { System.out.println("连接FTP失败."); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); System.out.println("文件读取错误。"); e.printStackTrace(); } } /** * 下载文件 * * @param ftpPath 文件路径 * @param fileName 文件名 * @return * @date 2019/3/14 13:13 */ public static void downloadFtpFile(String ftpPath, String fileName, OutputStream out) { FTPClient ftpClient = null; try { ftpClient = getFTPClient(); ftpClient.setControlEncoding("UTF-8"); // 中文支持 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); ftpClient.changeWorkingDirectory(ftpPath); ftpClient.retrieveFile(fileName, out); ftpClient.logout(); } catch (FileNotFoundException e) { System.out.println("没有找到" + ftpPath + "文件"); e.printStackTrace(); } catch (SocketException e) { System.out.println("连接FTP失败."); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); System.out.println("文件读取错误。"); e.printStackTrace(); } } /** * 把ftp上的文件copy到指定目录文件下 * * @param getDirPath //源文件路径 * @param path //FTP服务器中文件所在路径 * @param fileName //文件全名(加上后缀) * @date 2020/3/13 9:37 */ public static String retrieveFile(String getDirPath, String path, String fileName) { OutputStream out = null; InputStream inputStream = null; try { out = new ByteArrayOutputStream(); downloadFtpFile(getDirPath, out); inputStream = new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray()); return uploadFile(path, fileName, inputStream); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { out.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 文件下载 * * @param ftpPathAndFileName 文件路径+文件名 即上传文件成功后返回的路径 * @param out */ public static void downloadFtpFile(String ftpPathAndFileName, OutputStream out) { Map<String, String> map = extractFtpPathAndFileName(ftpPathAndFileName); downloadFtpFile(map.get("ftpPath"), map.get("FileName"), out); } /** * Description: 向FTP服务器上传文件 * * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa * @param fileName ftp文件名称 * @param input 文件流 * @return 成功返回路径加文件名, 失败返回null */ public static String uploadFile(String ftpPath, String fileName, InputStream input) { if (StringUtils.isBlank(ftpPath) || StringUtils.isBlank(fileName) || input == null) { return null; } if (ftpPath.charAt(ftpPath.length() - 1) != '/') { ftpPath += "/"; } ftpPath = pathPrefix + ftpPath; FTPClient ftpClient = null; try { int reply; ftpClient = getFTPClient(); reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return null; } BufferedInputStream bufferedInputStream = new BufferedInputStream(input); ftpClient.setBufferSize(1024 * 1024); ftpClient.setControlEncoding("UTF-8"); // 中文支持 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); createDir(ftpPath); ftpClient.changeWorkingDirectory(ftpPath); ftpClient.storeFile(fileName, bufferedInputStream); input.close(); ftpClient.logout(); return ftpPath + fileName; } catch (IOException e) { // e.printStackTrace(); log.error("ftp文件上传异常----->" + e.getMessage(), e); return null; } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException ioe) { log.error("ftp流关闭异常----->" + ioe.getMessage(), ioe); } } } } /** * 上传文件 * * @param ftpPath * @param file * @return 返回ftpPath和文件名拼接的路径 */ public static String uploadFile(String ftpPath, MultipartFile file) throws IOException { if (StringUtils.isBlank(ftpPath) || file == null || file.isEmpty()) { return null; } String fileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); String b = uploadFile(ftpPath, fileName, file.getInputStream()); if (b != null) { return b; } return null; } /** * 转换文件路径 * * @param fileTypeEnum 文件类型 * @return */ public static String getFilePathStr(FileTypeEnum fileTypeEnum) { //定义日期 Date date = new Date(); Calendar c = Calendar.getInstance(); c.setTime(date); String day = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DATE); String fileType = fileTypeEnum.getMsg(); String filePathStr = day + "/" + fileType; return filePathStr; } /** * 创建目录(有则切换目录,没有则创建目录) * * @param dir * @return */ public static boolean createDir(String dir) { FTPClient ftpClient = getFTPClient(); if (!StringUtils.isNotBlank(dir)) { return true; } String d; try { //目录编码,解决中文路径问题 d = new String(dir.toString().getBytes("GBK"), "iso-8859-1"); //尝试切入目录 if (ftpClient.changeWorkingDirectory(d)) { return true; } String[] arr = dir.split("/"); StringBuffer sbfDir = new StringBuffer(); //循环生成子目录 for (String s : arr) { sbfDir.append("/"); sbfDir.append(s); //目录编码,解决中文路径问题 d = new String(sbfDir.toString().getBytes("GBK"), "iso-8859-1"); //尝试切入目录 if (ftpClient.changeWorkingDirectory(d)) { continue; } if (!ftpClient.makeDirectory(d)) { // System.out.println("[失败]ftp创建目录:" + sbfDir.toString()); log.error("[失败]ftp创建目录:" + sbfDir.toString()); return false; } System.out.println("[成功]创建ftp目录:" + sbfDir.toString()); } //将目录切换至指定路径 return ftpClient.changeWorkingDirectory(d); } catch (Exception e) { e.printStackTrace(); log.error("文件目录切换/创建异常----->" + e.getMessage(), e); return false; } } /** * * 删除文件 * * * @param pathName FTP服务器保存目录 * @param fileName 要删除的文件名称 * @return */ public static boolean deleteFile(String pathName, String fileName) { FTPClient ftpClient = getFTPClient(); boolean flag = false; try { System.out.println("开始删除文件"); // 切换FTP目录 ftpClient.changeWorkingDirectory(pathName); ftpClient.dele(fileName); ftpClient.logout(); flag = true; System.out.println("删除文件成功"); } catch (Exception e) { System.out.println("删除文件失败"); e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } } } return flag; } /** * 删除文件 * * @param ftpPathAndFileName 文件路径+文件名 即上传文件成功后返回的路径 * @return */ public static boolean deleteFile(String ftpPathAndFileName) { Map<String, String> map = extractFtpPathAndFileName(ftpPathAndFileName); return deleteFile(map.get("ftpPath"), map.get("FileName")); } /** * 通过路径获取ftp路径和文件名 * * @param ftpPathAndFileName * @return */ public static Map<String, String> extractFtpPathAndFileName(String ftpPathAndFileName) { if (StringUtils.isBlank(ftpPathAndFileName) || ftpPathAndFileName.lastIndexOf("/") <= 0 || ftpPathAndFileName.charAt(ftpPathAndFileName.length() - 1) == '/' ) { throw new IllegalArgumentException("ftpPathAndFileName参数错误,该参数为文件路径+文件名"); } Map<String, String> ret = new HashMap<>(); String ftpPath = ftpPathAndFileName.substring(0, ftpPathAndFileName.lastIndexOf("/") + 1); String FileName = ftpPathAndFileName.substring(ftpPathAndFileName.lastIndexOf("/") + 1); ret.put("ftpPath", ftpPath); ret.put("FileName", FileName); return ret; } } FileTypeEnum枚举: @Getter @Slf4j public enum FileTypeEnum { IDCARDZ(1, "xx", "xxImg"), IDCARDF(2, "yyy", "yyyImg"), FileTypeEnum(Integer code, String msg, String path) { this.code = code; this.path = path; this.msg = msg; } private Integer code; private String msg; private String path; public static String getPath(Integer code) { if (code == null) { throw new BDException("未知文件类型"); } Optional<FileTypeEnum> optional = stream(FileTypeEnum.values()).filter(x -> Objects.equals(x.code, code)).findFirst(); if (optional.isPresent()) { return optional.get().path; } throw new BDException("未知文件类型"); } public static FileTypeEnum getEnum(Integer code) { if (code == null) { return null; } return stream(FileTypeEnum.values()).filter(x -> Objects.equals(x.code, code)).findFirst().orElse(null); } }

 

最新回复(0)