package org.jeecg.modules.iot.util; /** * @Description: Ftp配置 * @Author: cuikaidong * @Date: 2024-12-10 * @Version: V1.0 */ 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.FTPReply; import org.springframework.beans.factory.annotation.Value; import java.io.*; import java.net.SocketException; public class FtpUtil { private final static Log logger = LogFactory.getLog(FtpUtil.class); /** * 本地字符编码 */ private static String LOCAL_CHARSET = "GBK"; // FTP协议里面,规定文件名编码为iso-8859-1 private static String SERVER_CHARSET = "ISO-8859-1"; //ftp服务器IP地址 private static String ftpHost = "192.168.1.123"; //ftp服务器端口 private static int ftpPort = 21; //ftp服务器用户名 private static String ftpUserName = "admin"; //ftp服务器密码 private static String ftpPassword = "lx@2024"; /** * 验证FTP连接是否可用 * * @return true:连接成功;false:连接失败 */ public static boolean testFtpConnection() { FTPClient ftpClient = new FTPClient(); try { // 连接FTP服务器 ftpClient.connect(ftpHost, ftpPort); // 登录验证 boolean loginResult = ftpClient.login(ftpUserName, ftpPassword); // 检查连接状态和登录结果 int replyCode = ftpClient.getReplyCode(); boolean isConnected = FTPReply.isPositiveCompletion(replyCode) && loginResult; if (isConnected) { logger.info("FTP连接验证成功!"); } else { logger.error("FTP连接失败:用户名/密码错误或服务器不可达"); } return isConnected; } catch (SocketException e) { logger.error("FTP服务器IP地址错误或端口被占用:" + e.getMessage()); } catch (IOException e) { logger.error("FTP连接异常:" + e.getMessage()); } finally { // 释放资源 if (ftpClient.isConnected()) { try { ftpClient.logout(); ftpClient.disconnect(); } catch (IOException e) { logger.warn("关闭FTP连接时发生异常:" + e.getMessage()); } } } return false; } /** * 获取FTPClient对象 * * @return */ public static FTPClient getFTPClient() { FTPClient ftpClient = null; try { ftpClient = new FTPClient(); ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器 ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器 if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { logger.info("未连接到FTP,用户名或密码错误。"); ftpClient.disconnect(); } else { logger.info("FTP连接成功。"); } } catch (SocketException e) { e.printStackTrace(); logger.info("FTP的IP地址可能错误,请正确配置。"); } catch (IOException e) { e.printStackTrace(); logger.info("FTP的端口错误,请正确配置。"); } return ftpClient; } /** * 从FTP服务器下载文件 * * @param ftpHost FTP IP地址 * @param ftpUserName FTP 用户名 * @param ftpPassword FTP用户名密码 * @param ftpPort FTP端口 * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa * @param localPath 下载到本地的位置 格式:H:/download * @param fileName 文件名称 */ public static void downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String localPath, String fileName) { FTPClient ftpClient = null; try { ftpClient = getFTPClient(); // 设置上传文件的类型为二进制类型 if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). LOCAL_CHARSET = "UTF-8"; } ftpClient.setControlEncoding(LOCAL_CHARSET); ftpClient.enterLocalPassiveMode();// 设置被动模式 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式 // 上传文件 //对中文文件名进行转码,否则中文名称的文件下载失败 String fileNameTemp = new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET); ftpClient.changeWorkingDirectory(ftpPath); InputStream retrieveFileStream = ftpClient.retrieveFileStream(fileNameTemp); // 第一种方式下载文件(推荐) /* File localFile = new File(localPath + File.separatorChar + fileName); OutputStream os = new FileOutputStream(localFile); ftpClient.retrieveFile(fileName, os); os.close();*/ // 第二种方式下载:将输入流转成字节,再生成文件,这种方式方便将字节数组直接返回给前台jsp页面 byte[] input2byte = input2byte(retrieveFileStream); byte2File(input2byte, localPath, fileName); if (null != retrieveFileStream) { retrieveFileStream.close(); } } catch (FileNotFoundException e) { logger.error("没有找到" + ftpPath + "文件"); e.printStackTrace(); } catch (SocketException e) { logger.error("连接FTP失败."); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); logger.error("文件读取错误。"); e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { //退出登录 ftpClient.logout(); //关闭连接 ftpClient.disconnect(); } catch (IOException e) { } } } } /** * Description: 向FTP服务器上传文件 * * @param basePath FTP服务器基础目录 * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath * @param filename 上传到FTP服务器上的文件名 * @param input 输入流 * @return 成功返回true,否则返回false */ public static boolean uploadFile(String basePath, String filePath, String filename, InputStream input) { boolean result = false; FTPClient ftpClient = null; try { int reply; ftpClient = getFTPClient(); reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return result; } // 切换到上传目录 if (!ftpClient.changeWorkingDirectory(basePath + filePath)) { // 如果目录不存在创建目录 String[] dirs = filePath.split("/"); String tempPath = basePath; for (String dir : dirs) { if (null == dir || "".equals(dir)) continue; tempPath += "/" + dir; if (!ftpClient.changeWorkingDirectory(tempPath)) { if (!ftpClient.makeDirectory(tempPath)) { return result; } else { ftpClient.changeWorkingDirectory(tempPath); } } } } // 设置上传文件的类型为二进制类型 if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). LOCAL_CHARSET = "UTF-8"; } ftpClient.setControlEncoding(LOCAL_CHARSET); ftpClient.enterLocalPassiveMode();// 设置被动模式 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式 // 上传文件 filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET); if (!ftpClient.storeFile(filename, input)) { return result; } if (null != input) { input.close(); } result = true; } catch (IOException e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { //退出登录 ftpClient.logout(); //关闭连接 ftpClient.disconnect(); } catch (IOException ioe) { } } } return result; } /** * 删除文件 未测试 * * @param ftpHost FTP服务器地址 * @param ftpPort FTP服务器端口号 * @param ftpUserName FTP登录帐号 * @param ftpPassword FTP登录密码 * @param pathname FTP服务器保存目录 * @param filename 要删除的文件名称 * @return */ public static boolean deleteFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String pathname, String filename) { boolean flag = false; FTPClient ftpClient = new FTPClient(); try { ftpClient = getFTPClient(); // 验证FTP服务器是否登录成功 int replyCode = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(replyCode)) { return flag; } // 切换FTP目录 ftpClient.changeWorkingDirectory(pathname); // 设置上传文件的类型为二进制类型 if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). LOCAL_CHARSET = "UTF-8"; } ftpClient.setControlEncoding(LOCAL_CHARSET); ftpClient.enterLocalPassiveMode();// 设置被动模式 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置传输的模式 //对中文名称进行转码 filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET); ftpClient.dele(filename); flag = true; } catch (Exception e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { //退出登录 ftpClient.logout(); //关闭连接 ftpClient.disconnect(); } catch (IOException e) { } } } return flag; } /** * 创建文件夹 * * @param pathname * @param filename * @return */ public static boolean createFolder(String pathname, String filename) { boolean flag = false; FTPClient ftpClient = new FTPClient(); try { ftpClient = getFTPClient(); // 验证FTP服务器是否登录成功 int replyCode = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(replyCode)) { return flag; } // 切换FTP目录 ftpClient.changeWorkingDirectory(pathname); boolean created = ftpClient.makeDirectory(filename); if (created) { logger.info(filename + "文件夹创建成功"); } else { logger.info(filename + "创建文件夹失败"); } flag = true; } catch (Exception e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { //退出登录 ftpClient.logout(); //关闭连接 ftpClient.disconnect(); } catch (IOException e) { } } } return flag; } public static void uploadFolder(File localFolder, String remoteFolder) { if (!localFolder.exists()) { return; } FTPClient ftpClient = getFTPClient(); try { // 创建远程文件夹 if (!ftpClient.changeWorkingDirectory(remoteFolder)) { ftpClient.makeDirectory(remoteFolder); ftpClient.changeWorkingDirectory(remoteFolder); } } catch (IOException e) { e.printStackTrace(); } // 遍历本地文件夹中的文件和子文件夹 File[] files = localFolder.listFiles(); if (files != null) { for (File file : files) { if (file.isDirectory()) { // 递归上传子文件夹 uploadFolder(file, remoteFolder + "/" + file.getName()); } else { try { // 上传文件 uploadFile1(ftpClient, file, remoteFolder); } catch (IOException e) { e.printStackTrace(); } } } } } private static void uploadFile1(FTPClient ftpClient, File localFile, String remoteFolder) throws IOException { try (FileInputStream inputStream = new FileInputStream(localFile)) { ftpClient.storeFile(remoteFolder + "/" + localFile.getName(), inputStream); } } // 将字节数组转换为输入流 public static final InputStream byte2Input(byte[] buf) { return new ByteArrayInputStream(buf); } // 将输入流转为byte[] public static final byte[] input2byte(InputStream inStream) throws IOException { ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while ((rc = inStream.read(buff, 0, 100)) > 0) { swapStream.write(buff, 0, rc); } byte[] in2b = swapStream.toByteArray(); return in2b; } // 将byte[]转为文件 public static void byte2File(byte[] buf, String filePath, String fileName) { BufferedOutputStream bos = null; FileOutputStream fos = null; File file = null; try { File dir = new File(filePath); if (!dir.exists() && dir.isDirectory()) { dir.mkdirs(); } file = new File(filePath + File.separator + fileName); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); bos.write(buf); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }