注意点,如果登录ftp后,当前的目录里面没有自己想要的文件,则需要切换目录。如果当前目录就有自己需要的文件,则不需要切换目录。在读取文件和下载文件的时候文件目录为空字符串
import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.IOException; import java.net.SocketException; @Component public class FtpConnect { private static Logger logger = LoggerFactory.getLogger(FtpConnect.class); // FTP 登录用户名 @Value("${ftp.client.username}") private String userName; // FTP 登录密码 @Value("${ftp.client.password}") private String pwd; // FTP 服务器地址IP地址 @Value("${ftp.client.host}") private String host; // FTP 端口 @Value("${ftp.client.port}") private int port; /** * 连接ftp * * @return * @throws Exception */ public FTPClient getFTPClient() { FTPClient ftpClient = new FTPClient(); try { ftpClient = new FTPClient(); ftpClient.connect(host, port);// 连接FTP服务器 ftpClient.login(userName, pwd);// 登陆FTP服务器 if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { logger.info("未连接到FTP,用户名或密码错误。"); ftpClient.disconnect(); } ftpClient.enterLocalPassiveMode();// 设置被动模式 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置二进制传输 } catch (SocketException e) { logger.error("连接ftp失败!"); logger.info("FTP的IP地址可能错误,请正确配置。"); } catch (IOException e) { logger.error("连接ftp失败!"); logger.info("FTP的端口错误,请正确配置。"); } return ftpClient; } /** * 关闭连接 * * @param ftpClient */ public void close(FTPClient ftpClient) { try { if (ftpClient != null) { ftpClient.logout(); ftpClient.disconnect(); } } catch (IOException e) { logger.error("ftp连接关闭失败!"); } } }
import com.alibaba.fastjson.JSONObject; import org.apache.commons.net.ftp.FTPClient; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.io.*; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Calendar; @Component public class FtpUtil { private static Logger logger = LoggerFactory.getLogger(FtpUtil.class); public static final String DIRSPLIT = "/"; public static File downloadFile(FTPClient ftpClient, String targetPath, String localFilePath, String portalFtpFileUrl, String innerToken) throws Exception { OutputStream outputStream = null; try { String path = localFilePath; // File fileDire = new File(path); // if (!fileDire.exists() && !fileDire.isDirectory()) { // fileDire.mkdirs(); // } String name = targetPath.substring(targetPath.lastIndexOf("/") + 1); path = path + DIRSPLIT + name; File file = new File(path); if (file.exists()) { logger.info("file exist"); return file; } outputStream = new FileOutputStream(file); ftpClient.retrieveFile(targetPath, outputStream); // logger.info("Download file success. TargetPath: {}", targetPath); return file; } catch (Exception e) { logger.error("Download file failure. TargetPath: {}", targetPath); throw new Exception("Download File failure"); } finally { if (outputStream != null) { outputStream.close(); } } } private static JSONObject covertEntityToJSON(HttpEntity entity) throws Exception { if (entity != null) { String res = EntityUtils.toString(entity, "UTF-8"); JSONObject jsonObject = JSONObject.parseObject(res); return jsonObject; } else { return null; } } /** * 删除文件 * */ public static boolean deleteFile(File file) { boolean result = false; if (file.exists()) { if (file.delete()) { result = true; } } return result; } /** * 处理文件名绝对路径 * * @param filePath * @param fileName * @return P:/temp/1.txt 或者 p:/temp/x */ public static String pasreFilePath(String filePath, String fileName) { StringBuffer sb = new StringBuffer(); if (filePath.endsWith("/") || filePath.endsWith("\\")) { sb.append(filePath).append(fileName); } else { sb.append(filePath.replaceAll("\\\\", "/")).append("/").append(fileName); } return sb.toString(); } /** * 获取今天日期 - 数字格式 * * @return yyyyMMdd */ public static String getCurrentday() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, 0); return new SimpleDateFormat("yyyyMMdd").format(cal.getTime()); } /** * 获取昨天日期 - 数字格式 * * @return yyyyMMdd */ public static String getYesterday() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); return new SimpleDateFormat("yyyyMMdd").format(cal.getTime()); } }
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFileFilter; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; /** * @Author: luojie * @Date: 2020/12/21 16:38 */ @Component public class ScheduledConfig { private static Logger LOG = LoggerFactory.getLogger(ScheduledConfig.class); @Autowired private FtpConnect connect; // FTP 登录用户名 @Value("${ftp.filePath}") private String filePath; @Value("${base.filePath}") private String localFilePath; @Autowired private BaseConfig baseConfig; private long sleepTime = 60000; private long total = 10; private long num = 0; public static final String UNDERLINE = "_"; public static final String preFileName = ".jpg"; @Scheduled(cron = "0 0/3 * * * ?") public void importSPserviceinfo() { String readSPservicePathDay = filePath; LOG.info("文件路径:" + readSPservicePathDay); Date date = DateUtils.addHours(new Date(), -9); // String dateStr = "2022-01-01 00:00:00"; ftpGetAfterTime(localFilePath, readSPservicePathDay, date); } /** * 读取大于当前时间的文件 * @param localFilePath * @param ftpFilePath * @param timestamp */ public void ftpGetAfterTime(String localFilePath, String ftpFilePath, Date timestamp){ FTPClient ftpClient = null; FTPFile[] ftpFiles = null; try { ftpClient = connect.getFTPClient(); // 登录后的当前目录没有需要的文件,则需要执行下面的代码 跳转到指定目录 // ftpClient.changeWorkingDirectory(ftpFilePath); ftpClient.enterLocalPassiveMode(); ftpFiles = ftpClient.listFiles("", new FTPFileFilter() { @Override public boolean accept(FTPFile file) { if (file.isFile()){ Calendar timestampR = file.getTimestamp(); Date date = timestampR.getTime(); if(timestamp!=null && date.getTime()<timestamp.getTime()){ return false; } String name = file.getName(); String suffix = name.substring(name.lastIndexOf(".") + 1); if(!"jpg".equalsIgnoreCase(suffix)){ return false; } return true; } return false ; }}); List<String> filenames = new ArrayList<>(); if(ftpFiles != null && ftpFiles.length > 0){ for (FTPFile ftpFile : ftpFiles) { String name = ftpFile.getName();
//登录后的目录没有需要的文件,name前面需要加上文件的路径 // File file = FtpUtil.downloadFile(ftpClient, ftpFilePath + "/" + name, localFilePath, baseConfig.getPortalFtpFileUrl(), baseConfig.getInnerToken());
//登录后的目录里面就有需要的文件,name前面不需要加路径 File file = FtpUtil.downloadFile(ftpClient, name, localFilePath, baseConfig.getPortalFtpFileUrl(), baseConfig.getInnerToken()); // pushFile(file, baseConfig.getPortalFtpFileUrl(), baseConfig.getInnerToken(), name); // filenames.add(name); } } // System.out.println(JSON.toJSONString(filenames)); } catch (Exception e1) { e1.printStackTrace(); LOG.error("ftp连接异常"); }finally { connect.close(ftpClient); } } /** * 获取远程目录下的文件到容器 * localFilePath 本地存放文件的目录 * ftpFilePath ftp服务器存放文件的目录 */ public List<File> sftpGet(String localFilePath, String ftpFilePath) { FTPClient ftpClient = null; FTPFile[] ftpFiles = null; List<File> files = new ArrayList<File>(); try { ftpClient = connect.getFTPClient(); // 跳转到指定目录 ftpClient.changeWorkingDirectory(ftpFilePath); } catch (Exception e1) { LOG.error("ftp连接异常"); } try { //ftp client告诉ftp server开通一个端口来传输数据 ftpClient.enterLocalPassiveMode(); LOG.info("获得指定目录下的文件夹和文件信息"); ftpFiles = ftpClient.listFiles(); for (int i = 0; i < ftpFiles.length; i++) { FTPFile ftpfile = ftpFiles[i]; String name = ftpfile.getName(); Calendar timestampR = ftpfile.getTimestamp(); Date date = timestampR.getTime(); LOG.info(ftpfile.getName() + "," + date); if (".".equals(name) || "..".equals(name) || ftpfile.isDirectory()) { continue; } if (name.endsWith(preFileName)) { LOG.info("获取到目录下文件名:" + name); String sftpRemoteAbsolutePath = FtpUtil.pasreFilePath(ftpFilePath, name); // 远程服务器 File file = FtpUtil.downloadFile(ftpClient, sftpRemoteAbsolutePath, localFilePath, baseConfig.getPortalFtpFileUrl(), baseConfig.getInnerToken()); files.add(file); } } } catch (Exception e) { e.printStackTrace(); LOG.error(" sftpGet error"); LOG.error("次数" + num); if (num == total) { num = 0; throw new RuntimeException(e); } try { num += 1; Thread.sleep(sleepTime); importSPserviceinfo(); } catch (InterruptedException e1) { LOG.error("获取文件失败"); Thread.currentThread().interrupt(); } } finally { connect.close(ftpClient); } return files; } }
注意事项:
如果ftp的目录里面有中文,则需要转码
ftpPath = new String(ftpPath.getBytes("GBK"), "ISO-8859-1");
如果需要下载的文件的文件名称有中文,则需要转码
ftpFiles = ftpClient.listFiles("", new FTPFileFilter() { @Override public boolean accept(FTPFile file) { if (file.isFile()){ String n = file.getName(); LOG.info(file.getName()); try {
//文件名称有中文,需要转码 LOG.info(new String(n.getBytes("ISO-8859-1"), "GBK")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Calendar timestampR = file.getTimestamp(); Date date = timestampR.getTime(); LOG.info(DateUtil.date2String(date, DateUtil.Y_M_D_H_M)); if(timestamp!=null && date.getTime()<timestamp.getTime()){ return false; } String name = file.getName(); if(name.toLowerCase().endsWith(".doc") || name.toLowerCase().endsWith(".docx") || name.toLowerCase().endsWith(".pdf")){ map.put(name, new WarningFile(name, date)); return true; } return false; } return false ; }});