package com.opslab.util.ftp; import com.opslab.util.FileUtil; import com.opslab.util.valid; 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; import java.io.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * FTP工具类的实现 */ public class FTPUtilImpl implements FTPUtil { private Logger logger = Logger.getLogger(FTPUtilImpl.class); private FTPClient client; private FTPVo vo; public FTPUtilImpl(FTPVo vo) throws IOException { this.vo = vo; client = createFTPClien(vo); } //创建变连接FTP private FTPClient createFTPClien(FTPVo vo) { FTPClient client = new FTPClient(); int reply = -1; try { client.connect(vo.getHostName(), vo.getPort()); client.login(vo.getUsername(), vo.getPassword()); reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { client.disconnect(); return null; } else { client.setControlEncoding(vo.getRemoteEncoding()); client.setFileType(FTPClient.BINARY_FILE_TYPE); if (vo.isPassiveMode()) { client.enterLocalPassiveMode(); } else { client.enterRemotePassiveMode(); } client.cwd(vo.getRemoteDir()); } return client; } catch (IOException e) { e.printStackTrace(); return null; } } //通过FTP响应码判断是否操作成功 public boolean reply(String operation) { int replyCode = client.getReplyCode(); FTPLog log = new FTPLog(); log.setHost(vo.getHostName()); log.setOperation(operation); log.setLocalFile(""); log.setRemoteFile(""); log.setReplyCode(replyCode); log.setReplyCodeDesc(FTPConstant.REPLYCODE.get(replyCode)); logger.info(log); return FTPReply.isPositiveCompletion(replyCode); } public boolean reply(String operation, String localFile, String remoteFile) { int replyCode = client.getReplyCode(); FTPLog log = new FTPLog(); log.setHost(vo.getHostName()); log.setOperation(operation); log.setLocalFile(localFile); log.setRemoteFile(remoteFile); log.setReplyCode(replyCode); log.setReplyCodeDesc(FTPConstant.REPLYCODE.get(replyCode)); logger.info(log); return FTPReply.isPositiveCompletion(replyCode); } @Override public boolean isExists(String fileName) { List<String> list = listFile(vo.getRemoteDir()); if (list.contains(fileName)) { return true; } return false; } @Override public boolean downLoad(String fileName) { String localfileName = vo.getLocalDir() + File.separator + fileName; FileUtil.createFiles(localfileName); OutputStream out = null; try { out = new FileOutputStream(localfileName, true); client.retrieveFile(new String(fileName.getBytes(vo.getRemoteEncoding()), "ISO-8859-1"), out); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } return reply("DOWNLOAD", localfileName, fileName); } @Override public boolean downLoadDir(String directory) { List<String> files = listFile(directory); for (String s : files) { downLoad(s); } return true; } @Override public boolean deleteFile(String fileName) { if (isExists(fileName)) { try { client.deleteFile(new String(fileName.getBytes(vo.getRemoteEncoding()), "ISO-8859-1")); return reply("DELETE", "", fileName); } catch (IOException e) { e.printStackTrace(); } } return false; } @Override public boolean deleteDir(String directory) { List<String> files = listFile(directory); try { for (String s : files) { deleteFile(s); } List<String> dirs = listDir(directory); for (int i = dirs.size() - 1; i >= 0; i--) { client.removeDirectory(new String(dirs.get(i).getBytes(vo.getRemoteEncoding()), "ISO-8859-1")); } client.removeDirectory(new String(directory.getBytes(vo.getRemoteEncoding()), "ISO-8859-1")); } catch (IOException e) { e.printStackTrace(); } return reply("DELETE", "", directory); } @Override public boolean putFile(String fileName, String remoteFileName, boolean isDelete) { File file = new File(fileName); return putFile(file, remoteFileName, isDelete); } @Override public boolean putFile(File file, String remoteFileName, boolean isDelete) { String fileName = remoteFileName; String path = ""; String parent = getParentPath(remoteFileName); if (remoteFileName.lastIndexOf("/") != -1) { path = remoteFileName.substring(0, remoteFileName.lastIndexOf("/")); fileName = remoteFileName.substring(remoteFileName.lastIndexOf("/") + 1); mkDir(path); changeWorkDir(path); } try (InputStream in = new FileInputStream(file)) { if (isDelete) { deleteFile(new String(file.getName().getBytes(vo.getRemoteEncoding()), "ISO-8859-1")); } client.appendFile(new String(fileName.getBytes(vo.getRemoteEncoding()), "ISO-8859-1"), in); return reply("UPLOAD", file.getAbsoluteFile().toString(), remoteFileName); } catch (IOException e) { e.printStackTrace(); } return false; } @Override public boolean putDir(String fileName, String remoteDir) { File file = new File(fileName); return putDir(file, remoteDir); } @Override public boolean putDir(File file, String remoteDir) { List<File> list = FileUtil.listFile(file); for (File f : list) { String name = f.getAbsolutePath(); name = name.substring(name.indexOf(file.getName())).replaceAll("\\\\", "/"); putFile(f, remoteDir + "/" + name, true); } return true; } @Override public List<String> listFile(String directory) { List<String> list = new ArrayList<String>(); try { FTPFile[] files = client.listFiles(directory); for (int i = 0; i < files.length; i++) { String t = (directory + "/" + files[i].getName()).replaceAll("//", "/"); if (files[i].isFile()) { list.add(t); } else if (files[i].isDirectory()) { list.addAll(listFile((t + "/").replaceAll("//", "/"))); } } } catch (IOException e) { e.printStackTrace(); } return list; } @Override public Map<String,FileAttr> listFileAttr(String directory) { Map<String,FileAttr> map = new HashMap<String,FileAttr>(); try { FTPFile[] files = client.listFiles(directory); for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { FTPFile file = files[i]; String fileName = directory + file.getName(); FileAttr attr = new FileAttr(); attr.setFileName(fileName); attr.setModifyTime(file.getTimestamp().getTime()); attr.setSize(file.getSize()); map.put(fileName, attr); } else if (files[i].isDirectory()) { map.putAll(listFileAttr(directory + files[i].getName() + "/")); } } } catch (IOException e) { e.printStackTrace(); } return map; } @Override public boolean changeWorkDir(String directory) { try { client.cwd(directory); return true; } catch (IOException e) { e.printStackTrace(); } return false; } @Override public String getWorkDir() { try { return client.printWorkingDirectory(); } catch (IOException e) { e.printStackTrace(); } return ""; } @Override public boolean mkDir(String directory) { directory = directory.replaceAll("//", "/"); if (directory.startsWith("/")) { directory = directory.substring(1); } if (directory.endsWith("/")) { directory = directory.substring(0, directory.length() - 1); } try { String[] str = (new String(directory.getBytes(vo.getRemoteEncoding()), "ISO-8859-1")).split("/"); String t = ""; String parnet = ""; for (int i = 0; i < str.length; i++) { t += ("/" + str[i]); if (!isExists(t.substring(1))) { client.makeDirectory(str[i]); } client.changeWorkingDirectory(str[i]); parnet += "../"; } if (str.length >= 1) { client.changeWorkingDirectory(parnet); } } catch (IOException e) { e.printStackTrace(); } return false; } @Override public boolean changName(String oldName, String newName) { return false; } public LinkedList<String> listDir(String directory) { LinkedList<String> list = new LinkedList<String>(); try { FTPFile[] files = client.listFiles(directory); for (int i = 0; i < files.length; i++) { String t = (directory + "/" + files[i].getName()).replaceAll("//", "/"); if (files[i].isDirectory()) { list.add(t); list.addAll(listDir(t + "/")); } } } catch (IOException e) { e.printStackTrace(); } return list; } @Override public FTPClient client() { return client; } @Override public void destory() { if (valid.valid(client)) { try { client.disconnect(); } catch (IOException e) { e.printStackTrace(); } } } private String getParentPath(String file) { if (file.indexOf("/") != -1) { String temp = null; Pattern p = Pattern.compile("[/]+"); Matcher m = p.matcher(file); int i = 0; while (m.find()) { temp = m.group(0); i += temp.length(); } String parent = ""; for (int j = 0; j < i; j++) { parent += "../"; } return parent; } else { return "./"; } } private String getRelativePath(File path) { String path1 = path.getPath(); String path2 = path.getAbsolutePath(); return null; } }