ftp客户端类 FtpClient.java:
package org.crm.ftp; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; 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.hi.framework.HiConfigHolder; public class FtpClient { /** * 在hiFrameworkConfig.properties配置文件中可设置ip、ftp的用户名、ftp的密码、root */ private final static String FTPIP = HiConfigHolder.getProperty("hi.upload.ftp.ip"); private static int port = 21; private final static String FTPUSER = HiConfigHolder.getProperty("hi.upload.ftp.userName"); private final static String FTPPWD = HiConfigHolder.getProperty("hi.upload.ftp.password"); private final static String FTPROOT = HiConfigHolder.getProperty("hi.upload.ftp.root"); private final static int CLIENTSIZE = Integer.parseInt(HiConfigHolder.getProperty("hi.upload.ftp.clientSize")); private static List<FTPClient> ftpLists = new ArrayList<FTPClient>(); private static HashMap<FTPClient, Integer> ftpStatus = new HashMap<FTPClient, Integer >();// 0表示可用 1 表示不可用 static { } /** * FunName: 连接服务器 * @Author: sam * @Create Date: 2011-11-16 */ public static void connect(FTPClient ftp) throws IOException {//必要时,可以设置编码为gbk try { ftp.connect(FTPIP, port); int reply = ftp.getReplyCode();//连接ftp后返回值类型 if(!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); System.exit(0);//throw new IOException("服务器拒绝连接."); } else if(!ftp.login(FTPUSER, FTPPWD)) { ftp.logout(); throw new IOException("FTP用户名或密码!"); } ftp.setFileType(FTP.BINARY_FILE_TYPE);//使用二进制 if(FTPROOT != null && !"".equals(FTPROOT.trim())) { ftp.changeWorkingDirectory(FTPROOT);//改变目录路径 } } catch(IOException ex) { if(ftp.isConnected()) { try { ftp.disconnect(); } catch(IOException ioex) { System.err.println("断开服务器连接失败"); } } System.err.println(ex.getMessage()); } } /** * FunName: 断开重新连接 * @Author: sam * @Create Date: 2011-11-16 */ public static void reConnect(FTPClient ftp) throws IOException { try{ disConnect(ftp); }catch(IOException e){} connect(ftp); } /** * FunName: 断开连接 * @Author: sam * @Create Date: 2011-11-16 */ public static void disConnect(FTPClient ftp) throws IOException { try { ftp.noop(); // check that control connection is working OK ftp.logout(); } catch(IOException ioe) { System.err.println(ioe.getMessage()); } finally { if(ftp.isConnected()) System.err.println("FTP未断开连接"); } } /** * FunName: 关闭ftp * @Author: sam * @Create Date: 2011-11-16 */ public static void closeFtp(FTPClient ftp) throws IOException { if(ftpLists.indexOf(ftp) < 0) { disConnect(ftp); } else { ftpStatus.put(ftp, 0); } } /** * FunName: 获得一个ftp * @Author: sam * @Create Date: 2011-11-16 */ public synchronized static FTPClient getFtpClient() throws IOException { FTPClient ftp = null; for(FTPClient client : ftpLists) { //判断当前client是否已经有连接 if(ftpStatus.get(client) != null && ftpStatus.get(client).equals(new Integer(1))) { ftpStatus.put(client, 1); ftp = client; break; } } if(ftp == null) { //新建一个连接,放到ftpDownloads连接池 try { FTPClient newClient = new FTPClient(); connect(newClient); if(ftpLists.size() < CLIENTSIZE) { ftpLists.add(newClient); ftpStatus.put(newClient, 1); ftp = newClient; } } catch(IOException ioe) { LogFactory.getLog("/").error(ioe.getMessage()); } } if(!ftp.isAvailable()) {//判断ftp是否还保持连接状态 reConnect(ftp); } else { ftp.changeToParentDirectory(); if(FTPROOT != null && !"".equals(FTPROOT.trim())) ftp.changeWorkingDirectory(FTPROOT); } return ftp; } }
从ftp服务器下载文件 FtpDownload.java: package org.crm.ftp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.net.ftp.FTPClient; import org.hi.framework.web.BusinessException; import org.hi.i18n.util.I18NUtil; /* * ftp文件下载 */ public class FtpDownload { private FTPClient ftp; public FtpDownload() {//下载构造函数 try { ftp = FtpClient.getFtpClient(); } catch (IOException ioe) { throw new BusinessException(I18NUtil.getString("连接FTP服务器失败,原因:") + ioe.getMessage()); } } /** * FunName: 以文件流形式下载 * @Author: sam * @Create Date: 2011-11-16 */ public InputStream getDownloadIS(String path) throws IOException { ByteArrayInputStream bais = null; ByteArrayOutputStream baos = null; try { baos = new ByteArrayOutputStream(); ftp.retrieveFile(path, baos); bais = new ByteArrayInputStream(baos.toByteArray()); } catch (IOException e) {//抛异常时,重新连接 FtpClient.reConnect(ftp); baos = new ByteArrayOutputStream(); ftp.retrieveFile(path, baos); bais = new ByteArrayInputStream(baos.toByteArray()); } finally { bais.close(); baos.flush(); baos.close(); FtpClient.closeFtp(ftp); } return bais; } /** * FunName: 以文件形式下载 * @Author: sam * @Create Date: 2011-11-16 */ public void getDownloadFile(String path, File file) throws IOException { FileOutputStream fos = new FileOutputStream(file); try { ftp.retrieveFile(path, fos); } catch (IOException e) { FtpClient.reConnect(ftp); ftp.retrieveFile(path, fos); } finally { fos.flush(); fos.close(); FtpClient.closeFtp(ftp); } } }
上传文件到ftp服务器类 FtpUpload.java: package org.crm.ftp; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.httpclient.util.URIUtil; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.hi.framework.web.BusinessException; import org.hi.i18n.util.I18NUtil; public class FtpUpload { private FTPClient ftp; public FtpUpload() { try { ftp = FtpClient.getFtpClient(); } catch (IOException ioe) { throw new BusinessException(I18NUtil.getString("连接FTP服务器失败,原因:") + ioe.getMessage()); } } /** * 将文件保存到ftp并返回文件在ftp的地址 * @param is 要保存的文件的字节流 * @param fileName 文件名 * @param moduleName 保存在哪个目录中 * @throws IOException */ public String saveUploadIS(InputStream is, String fileName, String moduleName) throws IOException { if(moduleName == null || moduleName.equals("")) moduleName = "common"; try { changeDir(moduleName); fileName = formateName(URIUtil.encodeQuery(fileName));//url编码 ftp.storeUniqueFile(fileName, is); } catch (IOException ioe) {//出现异常,重新连接ftp FtpClient.reConnect(ftp); changeDir(moduleName); fileName = formateName(URIUtil.encodeQuery(fileName));//url编码 ftp.storeUniqueFile(fileName, is); } finally { is.close(); FtpClient.closeFtp(ftp); } return moduleName + "/" + fileName; } /** * 将文件保存到ftp并返回文件在ftp的地址 * @param file 要保存的文件 * @param fileName 文件名 * @param moduleName 保存在哪个目录中 * @throws IOException */ public String saveUploadFile(File file, String fileName,String moduleName) throws IOException { FileInputStream fis = new FileInputStream(file); return saveUploadIS(fis, fileName, moduleName); } /** * 将文件保存到ftp并返回文件在ftp的地址 * @param file 要保存的文件 * @throws IOException */ public String saveUploadFile(File file) throws IOException { String name = file.getName(); return saveUploadFile(file, name, "attachment"); } /* * 文件上传到该目录 */ private void changeDir(String dir) throws IOException { String sdir = serverDirs(dir); if(sdir == null || sdir.equals("")) {//目录不存在 ftp.makeDirectory(dir); ftp.changeWorkingDirectory(dir); } else { ftp.changeWorkingDirectory(sdir); } } public String serverDirs(String dir) throws IOException { FTPFile[] dirs = ftp.mlistDir(); if(dirs == null || dirs.length == 0) return ""; for(FTPFile oldDir : dirs) { if(dir.equalsIgnoreCase(oldDir.getName())) return oldDir.getName();//这里不返回dir } return ""; } private String formateName(String fileName) { String preName = "";//文件名,前缀 String extName = "";//文件格式,后缀 if(fileName.indexOf(".") < 0) preName = fileName;//没有格式文件 else { preName = fileName.substring(0,fileName.lastIndexOf(".")); extName = fileName.substring(fileName.lastIndexOf(".")); } List<String> names = getFtpFiles(""); int num = 1; while(names != null && names.contains(fileName)) {//重复文件改名 fileName = preName + "(" + num + ")" + extName; num ++; } return fileName; } /* * 获得相应目录下的所有文件 */ public List<String> getFtpFiles(String path) { List<String> names = new ArrayList<String>(); try { FTPFile[] ftpf = ftp.listFiles(path); for(FTPFile ff : ftpf) { names.add(ff.getName()); } } catch (IOException ioe) { System.err.println(ioe.getMessage()); } return names; } }
一个测试类FtpTest.java: package org.crm.ftp; import java.io.File; import java.io.IOException; import org.junit.Test; public class FtpTest{ @Test public void test() { FtpDownload fd = new FtpDownload(); try { fd.getDownloadFile("/attachment/675760a8gw1dl6d334nnxj(1).jpg", new File("d:/org.jpg")); } catch (IOException e) { e.printStackTrace(); } } @Test public void upload() { FtpUpload fu = new FtpUpload(); try { String path = fu.saveUploadFile(new File("d:/org.jpg")); System.err.println(path); } catch (IOException e) { e.printStackTrace(); } } }