ftp工具类
package com.xxx.zjdlbb.service.zjdlbb; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.SocketException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.apache.log4j.Logger; /** ******************************************************************************* * 文件名称:FTPService.java 系统名称: 类 概 述: FTP文件上传下载 创建日期:2015年4月3日 下午5:17:52 版 本: V1.0.0 ******************************************************************************* */ public class FTPService { private Logger log = Logger.getLogger(getClass()); protected static String FTP_CONTROL_ENCODING = "ISO-8859-1"; protected static String FTP_CHARSET_NAME; protected static String FTP_SYSTEM_TYPE; protected static String LOCAL_FILE_ENCODING = System.getProperty("file.encoding"); protected static String LOCAL_SYSTEM_TYPE = System.getProperty("os.name"); public static String FTP_CONTROL_ENCODING_LOCAL = "GBK"; /** * @Description 概要说明:上传文件到FTP服务器 * * @date 2015年4月6日 下午4:12:51 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param port * 端口 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * FTP保存文件的目录 * @param localFile * 本地需要上传的文件 * @return boolean */ public boolean upload(String ip, int port, String username, String pwd, String remoteDir, String localFile) { File in = new File(localFile); return upload(ip, port, username, pwd, remoteDir, in); } /** * @Description 概要说明:上传文件到FTP服务器 * * @date 2015年4月6日 下午4:12:51 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * FTP保存文件的目录 * @param localFile * 本地需要上传的文件 * @return boolean */ public boolean upload(String ip, String username, String pwd, String remoteDir, String localFile) { File in = new File(localFile); return upload(ip, username, pwd, remoteDir, in); } /** * @Description 概要说明:上传文件到FTP服务器 * * @date 2015年4月6日 下午4:12:51 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param port * 端口 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * FTP保存文件的目录 * @param in * 本地需要上传的文件 * @return boolean */ public boolean upload(String ip, int port, String username, String pwd, String remoteDir, File in) { boolean success = false; FTPClient ftp = new FTPClient(); try { // 建立连接、登录 success = login(ftp, ip, username, pwd); if (!success) { return success; } uploadFile(ftp, remoteDir, in); // 退出登录 ftp.logout(); success = true; } catch (IOException e) { log.error("", e); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return success; } /** * @Description 概要说明:上传文件到FTP服务器 * * @date 2015年4月6日 下午4:12:51 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * FTP保存文件的目录 * @param in * 本地需要上传的文件 * @return boolean */ public boolean upload(String ip, String username, String pwd, String remoteDir, File in) { boolean success = false; FTPClient ftp = new FTPClient(); try { // 建立连接、登录 success = login(ftp, ip, username, pwd); if (!success) { return success; } uploadFile(ftp, remoteDir, in); // 退出登录 ftp.logout(); success = true; } catch (IOException e) { log.error("", e); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return success; } /** * @Description 概要说明:本地文件上传到FTP指定目录 * * @date 2015年4月6日 下午4:16:10 * @update xxx(yyyy-MM-dd) * @param ftp * FTP对象 * @param remoteDir * FTP目录 * @param in * 本地文件 * @return void * @throws IOException */ public void uploadFile(FTPClient ftp, String remoteDir, File in) throws IOException { String fileName = in.getName(); try { if (!in.exists()) { throw new IOException("文件[" + fileName + "]不存在!"); } else { if (in.isDirectory()) { remoteDir = remoteDir + "/" + fileName; ftp.makeDirectory(local2Remote_encoding(remoteDir)); File[] files = in.listFiles(); for (File tmp : files) { uploadFile(ftp, remoteDir, tmp); } } else { uploadFile(ftp, remoteDir, fileName, in); } } log.info("[" + fileName + "/" + in.length() / 1024 + "KB]上传成功!"); } catch (IOException e) { log.info("[" + fileName + "]上传失败!"); throw e; } } /** * @Description 概要说明:文件上传 * * @date 2015年4月6日 下午4:54:21 * @update xxx(yyyy-MM-dd) * @param ftp * @param remoteDir * @param fileName * @param in * @throws IOException * void */ public void uploadFile(FTPClient ftp, String remoteDir, String fileName, File in) throws IOException { remoteDir = local2Remote_encoding(remoteDir + "/"); ftp.changeWorkingDirectory(remoteDir); fileName = local2Remote_encoding(fileName); InputStream input = null; try { log.debug("localFile:" + in.getAbsolutePath()); input = new FileInputStream(in); boolean isSucc = ftp.storeFile(fileName, input); if (!isSucc) { throw new IOException("文件[" + fileName + "/" + (in.getTotalSpace() / 1024) + "Kb]上传失败!"); } } catch (IOException e) { throw e; } finally { input.close(); } } /** * @Description 概要说明:从FTP上下载文件 * * @date 2015年4月3日 下午10:53:43 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * 需要下载的目标目录 * @param localDir * 本地保存目录 * @return boolean */ public List<File> download(String ip, String username, String pwd, String remoteDir, String localDir) { boolean success = false; FTPClient ftp = new FTPClient(); List<File> list = null; try { // 建立连接、登录 success = login(ftp, ip, username, pwd); if (!success) { return list; } list = downloadFile(ftp, remoteDir, localDir); // 退出登录 ftp.logout(); } catch (IOException e) { log.error("", e); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return list; } /** * @Description 概要说明:从FTP服务器上下载文件 * * @date 2015年4月3日 下午10:46:05 * @update xxx(yyyy-MM-dd) * @param ip * FTP服务器IP地址 * @param port * 端口号 * @param username * 用户名 * @param pwd * 密码 * @param remoteDir * 需要下载的目标目录 * @param localDir * 本地保存目录 * @return boolean */ public List<File> download(String ip, int port, String username, String pwd, String remoteDir, String localDir) { boolean success = false; FTPClient ftp = new FTPClient(); List<File> list = null; try { success = login(ftp, ip, port, username, pwd); if (!success) { return list; } list = downloadFile(ftp, remoteDir, localDir); ftp.logout(); } catch (IOException e) { log.error("", e); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return list; } /** * @Description 概要说明:过滤本目录以及父级目录 * * @date 2015年4月4日 上午12:00:15 * @update xxx(yyyy-MM-dd) * @param fs * @return List<FTPFile> */ protected List<FTPFile> filterSelf(FTPClient ftp, FTPFile[] fs) throws UnsupportedEncodingException { List<FTPFile> list = new ArrayList<FTPFile>(); for (FTPFile tmp : fs) { String tmpName = tmp.getName(); Pattern p1 = Pattern.compile("^\\.$"); Matcher m1 = p1.matcher(tmpName); Pattern p2 = Pattern.compile("^\\.\\.$"); Matcher m2 = p2.matcher(tmpName); boolean self1 = m1.find(); boolean self2 = m2.find(); if (!self1 && !self2) { list.add(tmp); } } return list; } /** * @Description 概要说明:文件过滤逻辑,重写自定义逻辑 * * @date 2015年4月3日 下午10:38:03 * @update xxx(yyyy-MM-dd) * @param fs * @return List<FTPFile> */ protected List<FTPFile> filter(FTPClient ftp, List<FTPFile> fs, Object... params) { List<FTPFile> files = new ArrayList<FTPFile>(); List<FTPFile> dirs = new ArrayList<FTPFile>(); for (FTPFile tmp : fs) { if (tmp.isDirectory()) { dirs.add(tmp); } else { files.add(tmp); } } files.addAll(dirs); return files; } /** * @Description 概要说明:下载文件到本地 * * @date 2015年4月3日 下午5:22:18 * @update xxx(yyyy-MM-dd) * @param ftp * ftp对象 * @param files * 远程主机文件集合 * @param localDir * 需要下载到本地目录 * @throws IOException * void */ public List<File> downloadFile(FTPClient ftp, String remoteDir, String localDir) throws IOException { String tmpRemote = local2Remote_encoding(remoteDir); ftp.changeWorkingDirectory("~"); ftp.changeWorkingDirectory(tmpRemote); FTPFile[] fs = ftp.listFiles(); List<File> list = new ArrayList<File>(); // 过滤文件 List<FTPFile> files = filter(ftp, filterSelf(ftp, fs)); // 递归下载 for (FTPFile file : files) { try { String tmpName = file.getName(); if (file.isDirectory()) { String remoteTmpDir = remoteDir + "/" + tmpName + "/"; String localTmpDir = localDir + "/" + tmpName + "/"; File localTmpFile = new File(localTmpDir); if (localTmpFile.exists()) { if (!localTmpFile.isDirectory()) { throw new IOException("文件[" + localTmpFile.getName() + "]不是目录!"); } } else { localTmpFile.mkdirs(); } list.addAll(downloadFile(ftp, remoteTmpDir, localTmpDir)); } else { File f = downloadFile(ftp, file, remoteDir, localDir); if (f != null) { list.add(f); log.info("文件[" + file.getName() + "/" + file.getSize() / (1024) + "KB]下载成功!"); } } } catch (IOException e) { log.info("文件[" + file.getName() + "]下载失败!"); throw e; } } return list; } /** * @Description 概要说明:下载文件到本地 * * @date 2015年4月3日 下午5:21:30 * @update xxx(yyyy-MM-dd) * @param ftp * ftp对象 * @param file * 远程主机文件 * @param localDir * 需要下载到本地目录 * @throws IOException * void */ public File downloadFile(FTPClient ftp, FTPFile file, String remoteDir, String localDir) throws IOException { String tmpName = file.getName(); ftp.changeWorkingDirectory("~"); remoteDir = local2Remote_encoding(remoteDir); ftp.changeWorkingDirectory(remoteDir); File localFile = new File(localDir + File.separator + tmpName); tmpName = local2Remote_encoding(tmpName); OutputStream os = null; boolean isSucc = false; try { log.debug("localFile:" + localFile.getAbsoluteFile()); os = new FileOutputStream(localFile); isSucc = ftp.retrieveFile(tmpName, os); if (isSucc) { return localFile; }/* * else{ try { InputStream in = ftp.retrieveFileStream("/"+remoteDir+"/"+tmpName); int len = -1; byte[] readB = new byte[1024]; while ((len = in.read(readB)) != -1) { os.write(readB, 0, len); os.flush(); } isSucc = true; return localFile; } catch (IOException e) { throw e; } } */ return null; } catch (IOException e) { throw e; } finally { os.close(); if (!isSucc && localFile.exists()) { log.warn("文件[" + tmpName + "/" + (file.getSize() / 1024) + "Kb]下载失败!"); localFile.delete(); } } } /** * @Description 概要说明:登录FTP * * @date 2015年4月3日 下午5:22:44 * @update xxx(yyyy-MM-dd) * @param ftp * FTP对象 * @param ip * FTP主机IP地址 * @param port * 端口 * @param username * 用户名 * @param pwd * 密码 * @return * @throws SocketException * @throws IOException * boolean */ protected boolean login(FTPClient ftp, String ip, int port, String username, String pwd) throws SocketException, IOException { ftp.connect(ip, port); ftp.login(username, pwd); int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return false; } log.info("FTP Server IP:" + ip); log.info("FTP Server User:" + username + " login success."); reply = ftp.sendCommand("OPTS UTF8", "ON"); if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). FTP_CONTROL_ENCODING_LOCAL = "UTF-8"; } FTP_SYSTEM_TYPE = ftp.getSystemType(); FTP_CHARSET_NAME = ftp.getCharsetName(); FTP_CONTROL_ENCODING = ftp.getControlEncoding(); // 解决文件名乱码问题 ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL); ftp.enterLocalPassiveMode();// 设置被动模式 ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式 return true; } /** * @Description 概要说明:登录FTP * * @date 2015年4月3日 下午5:23:25 * @update xxx(yyyy-MM-dd) * @param ftp * FTP对象 * @param ip * FTP主机IP地址 * @param username * 用户名 * @param pwd * 密码 * @return * @throws SocketException * @throws IOException * boolean */ protected boolean login(FTPClient ftp, String ip, String username, String pwd) throws SocketException, IOException { ftp.connect(ip); ftp.login(username, pwd); int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return false; } log.info("FTP Server IP:" + ip); log.info("FTP Server User:" + username + " login success."); reply = ftp.sendCommand("OPTS UTF8", "ON"); if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). FTP_CONTROL_ENCODING_LOCAL = "UTF-8"; } FTP_SYSTEM_TYPE = ftp.getSystemType(); FTP_CHARSET_NAME = ftp.getCharsetName(); FTP_CONTROL_ENCODING = ftp.getControlEncoding(); // 解决文件名乱码问题 ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL); ftp.enterLocalPassiveMode();// 设置被动模式 ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式 return true; } public String remote2Local_encoding(String remote) { String result = null; try { result = new String(remote.getBytes(FTP_CONTROL_ENCODING), FTP_CONTROL_ENCODING_LOCAL); } catch (UnsupportedEncodingException e) { log.error("", e); } return result; } public String local2Remote_encoding(String local) { String result = null; try { result = new String(local.getBytes(FTP_CONTROL_ENCODING_LOCAL), FTP_CONTROL_ENCODING); } catch (UnsupportedEncodingException e) { log.error("", e); } return result; } public String sys2Local_encoding(String sys) { String result = null; try { result = new String(sys.getBytes(), FTP_CONTROL_ENCODING_LOCAL); } catch (UnsupportedEncodingException e) { log.error("", e); } return result; } public String sys2Remote_encoding(String sys) { String result = null; try { result = new String(sys.getBytes(), FTP_CONTROL_ENCODING); } catch (UnsupportedEncodingException e) { log.error("", e); } return result; } /** * @Description 概要说明:是否最新文件 * * @date 2016年1月20日 下午3:49:47 * @update xxx(yyyy-MM-dd) * @param ftp * @param file * @param remoteDir * @return * @throws IOException * boolean */ public boolean isLast(FTPClient ftp, FTPFile file, String remoteDir) throws IOException { String tmpRemote = local2Remote_encoding(remoteDir); ftp.changeWorkingDirectory("~"); ftp.changeWorkingDirectory(tmpRemote); FTPFile[] ftpFiles = ftp.listFiles(); List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles)); long lastTime = 0; FTPFile tmpFile = null; for (FTPFile ftpFile : files) { long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis(); if (tmpLastTime > lastTime) { lastTime = tmpLastTime; tmpFile = ftpFile; } } return tmpFile == null ? false : file.getName().equals(tmpFile.getName()); } /** * @Description 概要说明:匹配结束字符文件 * @date 2016年1月20日 下午3:49:47 * @update xxx(yyyy-MM-dd) * @param file * FTP文件对象 * @param end * 结束字符 * @return * @throws IOException * boolean */ public boolean endWith(FTPFile file, String end) throws IOException { if (null == end) { end = ""; } return file.getName().endsWith(end); } public boolean isLastAndEndWith(FTPClient ftp, FTPFile file, String remoteDir, String end) throws IOException { if (file.getName().endsWith(end)) { String tmpRemote = local2Remote_encoding(remoteDir); ftp.changeWorkingDirectory("~"); ftp.changeWorkingDirectory(tmpRemote); FTPFile[] ftpFiles = ftp.listFiles(); List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles)); long lastTime = 0; FTPFile tmpFile = null; for (FTPFile ftpFile : files) { long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis(); if (ftpFile.getName().endsWith(end) && tmpLastTime > lastTime) { lastTime = tmpLastTime; tmpFile = ftpFile; } } return tmpFile == null ? false : file.getName().equals(tmpFile.getName()); } return false; } public static void main(String args[]) { FTPService ftp = new FTPService(); String ip = "127.0.0.1"; int port = 1111; String username = "crd"; String pwd = "crd"; String remoteDir = ""; String localDir = "C:/Users/Administrator/Desktop/test"; ftp.download(ip, port, username, pwd, remoteDir, localDir); System.out.println(122); } }