`
longforfreedom
  • 浏览: 196939 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Commons net之FTP

阅读更多

     最近用到FTP相关的操作,因为有伟大开源社区的存在,也不用自己再实现一把FTP协议了,看了下常用的FTP软件包,主要有Apache和Commons net中的Commons FTP和JDK中的自带的ftp操作类,看了下网友们写的例子,对比了一下。虽然我也不想每一个项目都依赖一堆外部JAR包,但还是选择采用Commons FTP,主要原因就是JDK中自带的是sun的内部包,并没有公开,并不能保证以后版本中能用。为方便使用,由于需要的功能也比较简单,也就做了下简单的封装。代码如下:

 

package org.migle.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;

import org.apache.commons.logging.Log;
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;

/**
 * FTP Client工具类,封装了<a href="http://commons.apache.org/net/">Jakarta Commons Net
 * FTPClient</a>对常用的功能如上传、下载 等功能提供简易操作,如果需要Jakarta Commons Net
 * FTPClient的全部功能可以通过{@link #getFtpclient()}
 * 得到org.apache.commons.net.ftp.FTPClient
 * 对象,对于org.apache.commons.net.ftp.FTPClient的全部功能有请查看 <a href =
 * "http://commons.apache.org/net/api/org/apache/commons/net/ftp/FTPClient.html"
 * > FTPClient API </a>
 * 
 * @since V2.0
 * @version V1.0 2010-2-26
 * @author 研发中心
 */
public class FTPClientUtil {

	private static Log logger = LogFactory.getLog(FTPClient.class);

	private FTPClient ftpclient;

	public FTPClientUtil(String host, int port) throws Exception {
		this(host, port, null, null);
	}

	public FTPClientUtil(String host, int port, String username, String password)
			throws Exception {
		ftpclient = new FTPClient();
		try {
			ftpclient.connect(host, port);
			int reply = ftpclient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftpclient.disconnect();
				logger.fatal("FTP服务器拒绝连接");
				throw new Exception("FTP服务器拒绝连接");
			}
			if (username != null) {
				if (!ftpclient.login(username, password)) {
					ftpclient.disconnect();
					logger.fatal("登陆验证失败,请检查账号和密码是否正确");
					throw new Exception("登陆验证失败,请检查账号和密码是否正确");
				}
			}
		} catch (SocketException e) {
			logger.fatal("无法连接至指定FTP服务器", e);
			throw new Exception(e);
		} catch (IOException e) {
			logger.fatal("无法用指定用户名和密码连接至指定FTP服务器", e);
			throw new Exception(e);
		}
	}

	/**
	 * 
	 * @param path
	 *            文件在FTP上存储的绝路径
	 * @param input
	 *            上传文
	 * @throws IOException
	 */
	public boolean upload(String pathname, InputStream input)
			throws IOException {
		// 是否是在根目录 下
		ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
		if (pathname.indexOf("/") != -1) {
			String path = pathname.substring(0, pathname.lastIndexOf("/"));
			mkdir(path);
		}
		return ftpclient.storeFile(new String(pathname.getBytes(), ftpclient.getControlEncoding()), input);
	}

	/**
	 * 从FTP服务器上下载pathname指定的文件,命名为localName
	 * 
	 * @param pathname
	 * @param localName
	 * @return
	 * @throws Exception
	 */
	public boolean download(String pathname, String localName) throws Exception {
		String filename = localName != null ? localName : pathname
				.substring(pathname.lastIndexOf("/") + 1);

		if (filename == null || filename.isEmpty()) {
			return false;
		}

		// 设置被动模式
		ftpclient.enterLocalPassiveMode();
		// 设置以二进制方式传输
		ftpclient.setFileType(FTP.BINARY_FILE_TYPE);

		if (ftpclient.listFiles(new String(pathname.getBytes(),ftpclient.getControlEncoding())).length == 0) {
			logger.fatal("下载文件不存在");
			throw new Exception("下载文件不存在");
		}

		File tmp = new File(filename + "_tmp"); // 临时文件
		File file = new File(filename);
		FileOutputStream output = null;
		boolean flag;
		try {
			output = new FileOutputStream(tmp);
			flag = ftpclient.retrieveFile(new String(pathname.getBytes(),ftpclient.getControlEncoding()), output);
			output.close();
			if (flag) {
				// 下载成功,重命名临时文件。
				tmp.renameTo(file);
				System.out.println(file.getAbsolutePath());
			}
		} catch (FileNotFoundException e) {
			logger.fatal("下载文件失败", e);
			throw new Exception(e);
		} finally {
			output.close();
		}

		return flag;
	}

	/**
	 * 只删除文件,如果删除空目录请用如下方法: <code>
	 * 	getFtpclient().removeDirectory(String pathname) 
	 * </code> 参考
	 * {@link org.apache.commons.net.ftp.FTPClient FTPClient}
	 * 
	 * @param pathname
	 * @return 成功删除返回true,否则返回false(如果文件不存在也返回false)
	 * @throws IOException
	 */
	public boolean delete(String pathname) throws IOException {
		return ftpclient.deleteFile(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
	}

	/**
	 * 改变当前目录至pathname,"/"代表根目录
	 * 
	 * @param pathname
	 *            路径名
	 * @return 如果改变成功返true否则返回false
	 * @throws IOException
	 */
	public boolean changeWorkingDirectory(String pathname) throws IOException {
		return ftpclient.changeWorkingDirectory(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
	}

	/**
	 * @return {@link org.apache.commons.net.ftp.FTPClient FTPClient}对象
	 */
	public FTPClient getFtpclient() {
		return this.ftpclient;
	}

	/**
	 * @param ftpclient
	 *            {@link org.apache.commons.net.ftp.FTPClient FTPClient}对象
	 */
	public void setFtpclient(FTPClient ftpclient) {
		this.ftpclient = ftpclient;
	}

	public void close() throws Exception {
		ftpclient.disconnect();
	}

	/**
	 * 
	 * @param pathname
	 *            要创建的目录路径,可以是相对路径,也可以是绝路径("/"开始)
	 * @return 如果成功创建目录返回true,否则返回false(如果目录已存在也返回false)
	 * @throws IOException
	 */
	public boolean mkdir(String pathname) throws IOException {
		//ftpclient.setControlEncoding("ISO-8859-1");
		//注意编码,如果不编码文件中文目录无法创建
		return ftpclient.makeDirectory(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
	}

	public static void main(String[] args) throws Exception {
		// URI uri = new URI(
		// "ftp://100.180.185.205/oracle_10201_database_win32/database/welcome.html");
		// System.out.println(uri.toURL().getHost());
		// System.out.println(uri.toURL().getPath());
		// System.out.println(uri.toURL().getFile());

		FTPClientUtil ftputil = new FTPClientUtil("100.180.185.205", 21, "username",
				"password");
		System.out.println(ftputil.mkdir("测试"));
		ftputil.close();
//		ftputil.upload("drop.sql", new FileInputStream("c:/drop.sql"));
//		ftputil.download("/drop.sql", "drop.sql");
		// FTPClient ftp = ftputil.getFtpclient();
		// FTPListParseEngine engine = ftp.initiateListParsing();
		// System.out.println(ftp.listFiles().length);
		// while (engine.hasNext()) {
		// FTPFile[] files = engine.getNext(25); // "page size" you want
		// }

		// FTPClient ftpclient = ftputil.getFtpclient();
		//
		// FTPFile[] f = ftpclient.listFiles("/kk/aa/drop2.sql");
		// System.out.println(f.length);
		// System.out.println(ftpclient.makeDirectory("/tt/aa/bb"));
		// System.out.println(ftpclient.getReplyString());
		// ftpclient.changeWorkingDirectory("/tt/aa/bb");
		//		
		// //System.out.println(ftpclient.deleteFile("/tt/aa/cc/"));
		// System.out.println(ftpclient.getReplyString());
		// ftpclient.changeWorkingDirectory("/");
		// System.out.println(ftpclient.listFiles().length);

//		System.out.println("a".lastIndexOf("/"));
	}
}
分享到:
评论
3 楼 longforfreedom 2010-08-12  
zhanglongchao 写道
你好我想问一下如何遍历ftp上的目录结构,并取出子文件的名称了,你有实例的话发给我,
谢谢你了,我的邮箱wnsx7218@qq.com

不好意思,最近不能上外网,才看到你的回复,你看看Commons net的API吧,是里面好像直接有一个方法(ListFiles吧我也忘记了)
2 楼 zhanglongchao 2010-07-30  
哦!我不需要下载文件,只要取出名字就OK了如何实现?
1 楼 zhanglongchao 2010-07-30  
你好我想问一下如何遍历ftp上的目录结构,并取出子文件的名称了,你有实例的话发给我,
谢谢你了,我的邮箱wnsx7218@qq.com

相关推荐

Global site tag (gtag.js) - Google Analytics