import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.SocketException; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPClientConfig; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.apache.log4j.Logger; import com.aspire.prm.app.iodd.common.remoteclient.RemoteClient; import com.aspire.prm.dmplt.basic.domain.FtpConfig; /** * name:FtpClient * <p> * </p> * * @author:lipeng * @data:2014-9-20 下午05:20:26 * @version 1.0 */ public class FtpClient implements RemoteClient { private FTPClient client = null; private FtpConfig config = null; private static final Logger logger = Logger.getLogger(FtpClient.class);; /** 当前工作目录,每次关闭连接要回复到null,因为当前类是单例类 */ private String workDirectory = null; /** 是否手工控制连接 */ private boolean handSwitch = false; /** true表示已经登录到ftp服务器 */ private boolean ready = false; /** * 初始化参数配置及创建commons.net.ftp的客户端 */ public FtpClient(FtpConfig config) { client = new FTPClient(); this.config = config; client.setControlEncoding(config.getRemoteEncoding()); // 设置当前工作目录 workDirectory = config.getRootPath(); } /** * 连接ftp * * @return * @throws SocketException * @throws IOException */ private boolean connect() throws SocketException, IOException { client.connect(config.getServer(), Integer.valueOf(config.getPort())); int reply; reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { client.disconnect(); logger.info("FTP server refused connection."); return false; } return true; } /** * 登入ftp * * @return * @throws IOException */ private boolean login() throws IOException { if (!client.login(config.getUsername(), config.getPassword())) { client.logout(); logger.info("FTP server login fail."); return false; } return true; } /** * 连接然后登入统一入口 * * @return * @throws SocketException * @throws IOException */ public boolean ready() throws SocketException, IOException { if (connect() && login()) { setConfig(); ready = true; return true; } return false; } /** * ftp运行环境参数配置 * * @throws IOException */ private void setConfig() throws IOException { FTPClientConfig conf = new FTPClientConfig(config.getFTPStyle()); client.configure(conf); // 被动传输模式 if (config.getPassiveMode()) client.enterLocalPassiveMode(); // 二进制传输模式 if (config.getBinaryFileType()) client.setFileType(FTP.BINARY_FILE_TYPE); // 设置当前工作目录 client.changeWorkingDirectory(getWorkDirectory()); } /** * 关闭连接 * * @throws IOException */ public void close() throws IOException { if (client.isConnected()) { client.logout(); client.disconnect(); // 也可设置为null workDirectory = config.getRootPath(); } ready = false; } /** * 获取等前工作目录的文件列表 * * @return * @throws IOException */ public String[] listFiles() throws IOException { if (!setReady()) { return null; } FTPFile[] files = client.listFiles(); int filesLength = files.length; String[] fileNameArr = new String[filesLength]; for (int i = 0; i < filesLength; i++) { fileNameArr[i] = files[i].getName(); } setClose(); return fileNameArr; } /** * 上传文件,文件名方式 * * @param path * @param name * @return * @throws Exception * @throws IOException */ public boolean uploadFile(String uploadFile, String remoteName) throws Exception { FileInputStream fis = null; try { if (!setReady()) { return false; } fis = new FileInputStream(uploadFile); if (remoteName.contains("/")) { String remotePath = remoteName.substring(0,remoteName.lastIndexOf("/")); client.makeDirectory(remotePath); remoteName=remoteName.substring(remoteName.lastIndexOf("/") + 1,remoteName.length()); client.changeWorkingDirectory(workDirectory+"/"+remotePath); } if (client.storeFile(remoteName, fis)) { logger.info(" upload success !!! "); return true; } client.changeWorkingDirectory(workDirectory); } catch (Exception e) { logger.error(" upload fail !!! "); throw e; } finally { if (fis != null) { try { fis.close(); } catch (Exception e2) { logger.error(e2.getMessage(), e2); } } setClose(); } return false; } /** * 上传文件,流方式 * * @param path * @param name * @return * @throws IOException */ public boolean uploadFile(InputStream stream, String name, String remoteName) { try { if (!setReady()) { return false; } if (client.storeFile(getWorkDirectory() + remoteName, stream)) { logger.info(" upload success !!! "); return true; } } catch (Exception e) { logger.error(" upload fail !!! "); return false; } finally { if (stream != null) { try { stream.close(); } catch (Exception e2) { logger.error(e2.getMessage(), e2); } } } return false; } /** * 下载文件 * * @param ftpFileName * @param localName * @return * @throws Exception */ public boolean downloadFile(String ftpFileName, String localName) throws Exception { FileOutputStream fos = null; try { File localFile=new File(localName); if(localFile!=null&&!localFile.exists()){ if(localFile.getParentFile()!=null&&!localFile.getParentFile().exists()){ localFile.getParentFile().mkdirs(); } localFile.createNewFile(); } fos = new FileOutputStream(localFile); if (!setReady()) { return false; } if (client.retrieveFile( new String(ftpFileName.getBytes(config.getLocalEncoding()), config.getRemoteEncoding()), fos)) { logger.info("download success !!! "); return true; } logger.info(" download fail !!! "); return false; } catch (Exception e) { logger.error("ftp下载文件失败ftpFileName:" + ftpFileName + ",localName" + localName, e); throw e; } finally { if (fos != null) { try { fos.close(); } catch (Exception e2) { } } } } /** * 删除文件 * * @param path * @param name * @return * @throws IOException */ public boolean removeFile(String name) throws Exception { if (!setReady()) { return false; } client.changeWorkingDirectory(config.getRootPath()); if (client.deleteFile(name)) { logger.info("remove file success !!! "); return true; } logger.info(" remove file fail !!! "); return false; } /** * 改变工作目录 * * @param path * @throws IOException */ public void setWorkDirectory(String path) throws IOException { workDirectory = (config.getRootPath() + path); // 如果是手动控制可以设置改变工作目录 if (handSwitch) { client.changeWorkingDirectory(workDirectory); } } /** * * 复制文件 * @param @param src * @param @param dst * @param @return * @param @throws Exception * @return boolean */ public boolean copyFile(String src,String dst) throws Exception { try { setReady(); if (dst.contains("/")) { String remotePath = dst.substring(0,dst.lastIndexOf("/")); client.makeDirectory(remotePath); } InputStream inputStream=client.retrieveFileStream(src); if (!client.completePendingCommand()) { return false; } // 如果读取的文件流不为空则复制文件 if (inputStream != null) { boolean tt= client.storeFile(dst, inputStream); // 关闭文件流 inputStream.close(); return tt; } return false; } catch (Exception e) { logger.error("ftp复制文件出错,[src:" + src+",dst:"+dst+"]", e); throw e; } } /** * 创建目录 * * @param pathname * @return * @throws IOException */ public boolean createDirectory(String pathname) throws IOException { if (!setReady()) { return false; } boolean okFlag = client.makeDirectory(pathname); setClose(); return okFlag; } /** * 获取当前工作目录 * * @return */ public String getWorkDirectory() { return workDirectory; } /** * 准备FTP连接环境 * * @return * @throws SocketException * @throws IOException */ private boolean setReady() throws SocketException, IOException { if (!ready) { if (!ready()) { logger.error("Ftp ready fail."); if (client.isConnected()) client.disconnect(); return false; } } ready = true; return true; } /** * 设置是否ftp连接 * * @throws IOException */ private void setClose() { try { if (!handSwitch) close(); } catch (Exception e) { logger.error("关闭ftp连接出错", e); } } /** * 打开手动连接 */ public void openHandSwitch() { handSwitch = true; } /** * 关闭手动连接 */ public void closeHandSwitch() { handSwitch = false; } }