`
yangyangmyself
  • 浏览: 233859 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Apache Common-net Ftp客户端实例

    博客分类:
  • Java
阅读更多
  本人参考Apache Common-net 2.2 的Api以及官方网的测试代码而写的FTP客户端操作实例,此外引用了dom4j开源包用于将FTP服务器的目录结构保存成XML文件。需实现断点续传的功能,还请高手多多指教。

package com.shine.Ftp.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

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.FTPListParseEngine;
import org.apache.commons.net.ftp.FTPReply;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class FtpHelper {

	private FTPClient ftp = null;
	/**
	 * Ftp服务器
	 */
	private String server;
	/**
	 * 用户名
	 */
	private String uname;
	/**
	 * 密码
	 */
	private String password;
	/**
	 * 连接端口,默认21
	 */
	private int port = 21;
	
	private Document document ;

	public FtpHelper(String server, int port, String uname,
			String password){
		this.server = server;
		if (this.port > 0){
			this.port = port;
		}
		this.uname = uname;
		this.password = password;
		//初始化
		ftp = new FTPClient();	
	}
	/**
	 * 连接FTP服务器
	 * 
	 * @param server
	 * @param uname
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public FTPClient connectFTPServer() throws Exception {
		try {
			ftp.configure(getFTPClientConfig());
			ftp.connect(this.server, this.port);
			if (!ftp.login(this.uname, this.password)) {
				ftp.logout();
				ftp = null;
				return ftp;
			}

			// 文件类型,默认是ASCII
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftp.setControlEncoding("GBK");
			// 设置被动模式
			ftp.enterLocalPassiveMode();
			ftp.setConnectTimeout(2000);
			ftp.setBufferSize(1024);
			// 响应信息
			int replyCode = ftp.getReplyCode();
			if ((!FTPReply.isPositiveCompletion(replyCode))) {
				// 关闭Ftp连接
				closeFTPClient();
				// 释放空间
				ftp = null;
				throw new Exception("登录FTP服务器失败,请检查![Server:" + server + "、"
						+ "User:" + uname + "、" + "Password:" + password);
			} else {
				return ftp;
			}
		} catch (Exception e) {
			ftp.disconnect();
			ftp = null;
			throw e;
		}
	}

	/**
	 * 配置FTP连接参数
	 * 
	 * @return
	 * @throws Exception
	 */
	public FTPClientConfig getFTPClientConfig() throws Exception {
		String systemKey = FTPClientConfig.SYST_NT;
		String serverLanguageCode = "zh";
		FTPClientConfig conf = new FTPClientConfig(systemKey);
		conf.setServerLanguageCode(serverLanguageCode);
		conf.setDefaultDateFormatStr("yyyy-MM-dd");
		return conf;
	}

	/**
	 * 向FTP根目录上传文件
	 * 
	 * @param localFile
	 * @param newName
	 *            新文件名
	 * @throws Exception
	 */
	public Boolean uploadFile(String localFile, String newName)
			throws Exception {
		InputStream input = null;
		boolean success = false;
		try {
			File file = null;
			if (checkFileExist(localFile)) {
				file = new File(localFile);
			}
			input = new FileInputStream(file);
			success = ftp.storeFile(newName, input);
			if (!success) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
		return success;
	}

	/**
	 * 向FTP根目录上传文件
	 * 
	 * @param input
	 * @param newName
	 *            新文件名
	 * @throws Exception
	 */
	public Boolean uploadFile(InputStream input, String newName)
			throws Exception {
		boolean success = false;
		try {
			success = ftp.storeFile(newName, input);
			if (!success) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
		return success;
	}

	/**
	 * 向FTP指定路径上传文件
	 * 
	 * @param localFile
	 * @param newName
	 *            新文件名
	 * @param remoteFoldPath
	 * @throws Exception
	 */
	public Boolean uploadFile(String localFile, String newName,
			String remoteFoldPath) throws Exception {

		InputStream input = null;
		boolean success = false;
		try {
			File file = null;
			if (checkFileExist(localFile)) {
				file = new File(localFile);
			}
			input = new FileInputStream(file);

			// 改变当前路径到指定路径
			if (!this.changeDirectory(remoteFoldPath)) {
				System.out.println("服务器路径不存!");
				return false;
			}
			success = ftp.storeFile(newName, input);
			if (!success) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
		return success;
	}

	/**
	 * 向FTP指定路径上传文件
	 * 
	 * @param input
	 * @param newName
	 *            新文件名
	 * @param remoteFoldPath
	 * @throws Exception
	 */
	public Boolean uploadFile(InputStream input, String newName,
			String remoteFoldPath) throws Exception {
		boolean success = false;
		try {
			// 改变当前路径到指定路径
			if (!this.changeDirectory(remoteFoldPath)) {
				System.out.println("服务器路径不存!");
				return false;
			}
			success = ftp.storeFile(newName, input);
			if (!success) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
		return success;
	}

	/**
	 * 从FTP服务器下载文件
	 * 
	 * @param remotePath
	 *            FTP路径(不包含文件名)
	 * @param fileName
	 *            下载文件名
	 * @param localPath
	 *            本地路径
	 */
	public Boolean downloadFile(String remotePath, String fileName,
			String localPath) throws Exception {

		BufferedOutputStream output = null;
		boolean success = false;
		try {
			// 检查本地路径
			this.checkFileExist(localPath);
			// 改变工作路径
			if (!this.changeDirectory(remotePath)) {
				System.out.println("服务器路径不存在");
				return false;
			}
			// 列出当前工作路径下的文件列表
			List<FTPFile> fileList = this.getFileList();
			if (fileList == null || fileList.size() == 0) {
				System.out.println("服务器当前路径下不存在文件!");
				return success;
			}
			for (FTPFile ftpfile : fileList) {
				if (ftpfile.getName().equals(fileName)) {
					File localFilePath = new File(localPath + File.separator
							+ ftpfile.getName());
					output = new BufferedOutputStream(new FileOutputStream(
							localFilePath));
					success = ftp.retrieveFile(ftpfile.getName(), output);
				}
			}
			if (!success) {
				throw new Exception("文件下载失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (output != null) {
				output.close();
			}
		}
		return success;
	}

	/**
	 * 从FTP服务器获取文件流
	 * 
	 * @param remoteFilePath
	 * @return
	 * @throws Exception
	 */
	public InputStream downloadFile(String remoteFilePath) throws Exception {

		return ftp.retrieveFileStream(remoteFilePath);
	}

	/**
	 * 获取FTP服务器上指定路径下的文件列表
	 * 
	 * @param filePath
	 * @return
	 */
	public List<FTPFile> getFtpServerFileList(String remotePath)
			throws Exception {

		FTPListParseEngine engine = ftp.initiateListParsing(remotePath);
		List<FTPFile> ftpfiles = Arrays.asList(engine.getNext(25));

		return ftpfiles;
	}

	/**
	 * 获取FTP服务器上[指定路径]下的文件列表
	 * 
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public List<FTPFile> getFileList(String remotePath) throws Exception {

		List<FTPFile> ftpfiles = Arrays.asList(ftp.listFiles(remotePath));

		return ftpfiles;
	}

	/**
	 * 获取FTP服务器[当前工作路径]下的文件列表
	 * 
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public List<FTPFile> getFileList() throws Exception {

		List<FTPFile> ftpfiles = Arrays.asList(ftp.listFiles());

		return ftpfiles;
	}

	/**
	 * 改变FTP服务器工作路径 
	 * 
	 * @param remoteFoldPath
	 */
	public Boolean changeDirectory(String remoteFoldPath) throws Exception {

		return ftp.changeWorkingDirectory(remoteFoldPath);
	}

	/**
	 * 删除文件
	 * 
	 * @param remoteFilePath
	 * @return
	 * @throws Exception
	 */
	public Boolean deleteFtpServerFile(String remoteFilePath) throws Exception {

		return ftp.deleteFile(remoteFilePath);
	}

	/**
	 * 创建目录
	 * 
	 * @param remoteFoldPath
	 * @return
	 */
	public boolean createFold(String remoteFoldPath) throws Exception {

		boolean flag = ftp.makeDirectory(remoteFoldPath);
		if (!flag) {
			throw new Exception("创建目录失败");
		}
		return false;
	}

	/**
	 * 删除目录
	 * @param remoteFoldPath
	 * @return
	 * @throws Exception
	 */
	public boolean deleteFold(String remoteFoldPath) throws Exception {
		
		return ftp.removeDirectory(remoteFoldPath) ;
	}

	/**
	 * 删除目录以及文件
	 * 
	 * @param remoteFoldPath
	 * @return
	 */
	public boolean deleteFoldAndsubFiles(String remoteFoldPath)
			throws Exception {

		boolean success = false;
		List<FTPFile> list = this.getFileList(remoteFoldPath);
		if (list == null || list.size() == 0) {
			return deleteFold(remoteFoldPath);
		}
		for (FTPFile ftpFile : list) {
			
			String name = ftpFile.getName();
			if (ftpFile.isDirectory()) {
				success = deleteFoldAndsubFiles(remoteFoldPath + "/" + name);
				if (!success)
					break;
			} else {
				success = deleteFtpServerFile(remoteFoldPath + "/" + name);
				if (!success)
					break;
			}
		}
		if (!success)
			return false;
		success = deleteFold(remoteFoldPath);
		return success;
	}

	/**
	 * 检查本地路径是否存在
	 * 
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public boolean checkFileExist(String filePath) throws Exception {
		boolean flag = false;
		File file = new File(filePath);
		if (!file.exists()) {
			throw new Exception("本地路径不存在,请检查!");
		} else {
			flag = true;
		}
		return flag;
	}
	
	/**
	 * 创建XML文件
	 * @return
	 */
	public Element getCurrentElement(){
		document = DocumentHelper.createDocument();
		return document.addElement("root");
	}
	
	/**
	 * 生成目录XML文件
	 */
	public void createDirectoryXML(String remotePath,Element fatherElement) throws Exception{

		List<FTPFile> list = this.getFileList();
		for(FTPFile ftpfile:list){
			Element currentElement = fatherElement; //当前的目录节点
			String newRemotePath = remotePath+ftpfile.getName();
			if(ftpfile.isDirectory()){
				Element dirElement = fatherElement.addElement("dir") ;
				dirElement.addAttribute("name",ftpfile.getName());
				currentElement = dirElement;
				this.changeDirectory(newRemotePath); //从根目录开始
				createDirectoryXML(newRemotePath,dirElement);
			}else{
				 Element fileElement = fatherElement.addElement("file");//文件节点
				 fileElement.setText(ftpfile.getName()) ;
			}
		}
	}
	
	/**
	 * 保存xml
	 */
	public void saveXML(){
		XMLWriter output = new XMLWriter();
        //输出格式化
        OutputFormat format = OutputFormat.createPrettyPrint();
        try {
            output = new XMLWriter(new FileWriter("src/com/shine/Ftp/config/dir.xml"), format);
            output.write(this.document);
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	/**
	 * 关闭FTP连接
	 * 
	 * @param ftp
	 * @throws Exception
	 */
	public void closeFTPClient(FTPClient ftp) throws Exception {

		try {
			if (ftp.isConnected())
				ftp.logout();
				ftp.disconnect();
		} catch (Exception e) {
			throw new Exception("关闭FTP服务出错!");
		}
	}

	/**
	 * 关闭FTP连接
	 * 
	 * @throws Exception
	 */
	public void closeFTPClient() throws Exception {

		this.closeFTPClient(this.ftp);
	}

	/**
	 * Get Attribute Method
	 * 
	 */
	public FTPClient getFtp() {
		return ftp;
	}

	public String getServer() {
		return server;
	}

	public String getUname() {
		return uname;
	}

	public String getPassword() {
		return password;
	}

	public int getPort() {
		return port;
	}

	/**
	 * Set Attribute Method
	 * 
	 */
	public void setFtp(FTPClient ftp) {
		this.ftp = ftp;
	}

	public void setServer(String server) {
		this.server = server;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setPort(int port) {
		this.port = port;
	}

	/**
	 * 主方法(测试)
	 * 
	 * 问题:上传时命名的新文件名不能有中文,否则上传失败.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			FtpHelper fu = new FtpHelper("192.168.2.18", 21, "administrator","sunshine");
			fu.connectFTPServer();
			Element fatherElement = fu.getCurrentElement();
			fu.createDirectoryXML("/", fatherElement);
			fu.saveXML();
		} catch (Exception e) {
			System.out.println("异常信息:" + e.getMessage());
		}
	}
}



  更新一下第469、474、474行的代码:
  String newRemotePath = (remotePath+"/"+ftpfile.getName()).replaceAll("//","/");
  String currentWorkPath = this.printWorkingDirectory();
  createDirectoryXML(currentWorkPath,dirElement);
 


提供源码:(只需配置好一台Ftp服务器即可用)
分享到:
评论
1 楼 shengjun828 2013-07-08  
this.printWorkingDirectory();
这个方法在哪里?

相关推荐

    Android 利用commons-net-3.3实现ftp上传下载Demo

    implementation 'org.apache.commons:commons-net:3.6' // 使用最新版本替代3.3 } ``` 然后,我们需要创建一个FTP客户端实例并配置连接参数,如服务器地址、端口号、用户名和密码。以下是一个简单的FTP连接示例: ...

    common-io,common-net打包奉送

    Apache Commons Net库(common-net)主要处理各种网络协议,包括FTP、Telnet、NNTP等。FTP部分提供了丰富的API,使得开发者可以轻松地执行FTP相关的任务。以下是一些关键功能: 1. FTP连接管理:创建和管理FTP连接...

    commons-net-3.6 jar包.zip

    在`commons-net-3.6.jar`这个版本中,我们主要关注FTP功能,因为这是该库最广泛使用的部分。 FTP支持是Apache Commons Net的核心功能之一。它提供了全面的FTP客户端实现,包括连接管理、文件上传、下载、列表操作、...

    利用commons-net包实现ftp上传下载例子

    标题中的“利用commons-net包实现ftp上传下载例子”是指通过Apache Commons Net库来实现FTP(File Transfer Protocol)的上传和下载功能。Apache Commons Net是Apache软件基金会开发的一个Java库,它提供了多种网络...

    FTP Jar包 Commons等 绝对能用

    "Commons-Net FTP"是该库中的核心模块,主要包含以下关键类和接口: 1. `FTPClient`:这是与FTP服务器交互的主要类,可以用来登录服务器、切换工作目录、列出目录内容、上传/下载文件等。 2. `FTPFile`:表示FTP...

    用于FTP文件传输的命令追踪

    Java的`common-net`工具包提供了FTP客户端的实现,使得开发者能够方便地在Java应用中集成FTP文件传输功能。Apache Log4j是Java日志记录框架,它提供了灵活的日志记录控制,有助于调试和追踪FTP文件传输过程中的问题...

    自动化测试相关包自动化测试相关包自动化测试相关包

    `Common-net`是Apache Commons项目的一部分,提供了各种网络相关的通用操作。这个库包含了很多实用工具类,如IP地址处理、FTP客户端、SMTP邮件发送、URL操作等。在自动化测试中,`Common-net`可以辅助进行网络环境的...

    FTP操作示例

    在实际使用中,需要确保正确添加了依赖的Apache Commons Net库,即`commons-net-x.x.jar`和`commons-net-ftp-x.x.jar`。在Maven或Gradle项目中,可以通过配置依赖管理来导入这些库。 总的来说,Apache Commons Net...

    java多线程ftp 上传下载

    正如描述中提到的,`common-net.jar`是实现这一目标的关键依赖包。 Apache Commons Net库包含了`FTPClient`类,它是实现FTP客户端功能的核心。首先,我们需要在项目中引入`common-net.jar`,可以通过Maven或Gradle...

    apache tomcat 集群

    Apache Tomcat 集群是实现高可用性和负载均衡的一种方法,它通过将多个Tomcat实例组合在一起,确保在任何单个实例失败时,服务仍然能够持续运行。Apache HTTP Server (通常称为Apache) 与Tomcat的集成,特别是通过...

    Java FTPClient连接池的实现

    Apache的common-pool工具包提供了开发通用对象池的一些接口和实现类,其中最基本的两个接口是ObjectPool和PoolableObjectFactory。ObjectPool接口中有几个最基本的方法: 1. addObject() : 添加对象到池 2. ...

    fastcgi 数据发送,跳转 实例

    FastCGI(Fast Common Gateway Interface)是一种协议,用于将Web服务器(如Apache)与外部程序(通常为PHP、Python或Perl解释器)进行通信,以处理动态内容。相比传统的CGI,FastCGI更高效,因为它在处理多个请求时...

    Prentice.Hall.PTR.A.Practical.Guide.to.Ubuntu.Linux.2008.pdf

    - Common Unix Printing System (CUPS) 的配置。 - 打印队列的管理。 - 多打印机环境的设置。 **4.5 构建内核** - **章节简介**:提供了构建Linux内核的方法。 - **核心知识点**: - 内核编译流程。 - 配置...

    Apache Commons source

    此外,Apache Commons 项目遵循良好的编程实践,代码结构清晰,注释详尽,是学习 Java 编程和设计模式的优秀实例。 在学习源码时,建议先了解每个模块的基本使用方法,然后逐步深入到具体类和方法的实现。分析源码...

Global site tag (gtag.js) - Google Analytics