`

使用commons-net对ftp文件上传下载

阅读更多

     项目中由于要使用到ftp服务,虽然之前对edtFTPj有研究,但是鉴于edtFTPj版本更新比较慢等原因,没有使用这个包,我们用的功能比较简单,先简单的介绍下。
     过程一般是先建立连接,登陆,然后执行命令,最后关闭连接,相对来说比较简单,直接上代码。
     需要说明的是,在写测试单元测试的时候,如果不依赖物理的ftp,就需要自己mock一个ftp了,我在网上找到一个mockFtpServer,具体用法大家可以参考。

package com.xxx.aaa.data.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.Calendar;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
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.FTPReply;

import com.xxx.aaa.common.aaaConfig;
import com.xxx.aaa.common.exception.aaaBaseException;
import com.xxx.aaa.common.log.LoggerHelper;
import com.xxx.aaa.common.util.DateUtils;
import com.xxx.aaa.util.aaaConstants;

public class FtpClient {

	private final FtpClientConfig ftpConfig;
	private final FTPClient client;
	private boolean ready = false;

	public FtpClient(FtpClientConfig config) {
		ftpConfig = config;
		client = new FTPClient();
	}

	public void begin() throws aaaBaseException {
		try {
			if (connect() && login()) {
				setConfig();
				ready = true;
			}
		} catch (SocketException e) {
			LoggerHelper.err(this.getClass(), "Connect socket error!", e);
			throw new aaaBaseException("Connect socket error,reaseon:" + e.getMessage());
		} catch (IOException e) {
			LoggerHelper.err(this.getClass(), "Login server error!", e);
			throw new aaaBaseException("Login server error,reaseon:" + e.getMessage());
		}
	}

	private boolean connect() throws SocketException, IOException {
		client.connect(ftpConfig.getServer(), ftpConfig.getPort());
		int reply = client.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			client.disconnect();
			LoggerHelper.info(this.getClass(), "Error connet server:{} on port:{}", ftpConfig.getServer(),
			        ftpConfig.getPort());
			return false;
		}
		return true;
	}

	private boolean login() throws IOException {
		boolean loginSuccess = client.login(ftpConfig.getUsername(), ftpConfig.getPassword());
		if (!loginSuccess) {
			client.logout();
			LoggerHelper.info(this.getClass(), "Error login username:{} with password:{}", ftpConfig.getUsername(),
			        ftpConfig.getPassword());
			return false;
		}
		return true;
	}

	/**
	 * ftp运行环境参数配置
	 * 
	 * @throws IOException
	 */
	private void setConfig() throws IOException {
		FTPClientConfig conf = new FTPClientConfig(ftpConfig.getFtpStyle());
		client.configure(conf);

		// 被动传输模式
		if (ftpConfig.getPassiveMode()) {
			client.enterLocalPassiveMode();
		}

		// 二进制传输模式
		if (ftpConfig.getBinaryFileType()) {
			client.setFileType(FTP.BINARY_FILE_TYPE);
		}

		// 设置当前工作目录
		client.changeWorkingDirectory(ftpConfig.getRootPath());
	}

	/**
	 * 下载文件
	 * 
	 * @param path
	 * @param name
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws IOException
	 */
	public String download(String fileName) throws aaaBaseException {
		if (!ready) {
			return "";
		}
		String localPath = aaaConfig.getTempDir();
		if (!localPath.endsWith("/")) {
			localPath = localPath + "/";
		}
		File file = null;
		FileOutputStream fos = null;
		String destFileName = generateDestFileName(fileName);
		try {
			file = new File(localPath + destFileName);
			FileUtils.forceMkdir(file.getParentFile());
			fos = new FileOutputStream(file);
			client.retrieveFile(fileName, fos);
			return destFileName;
		} catch (IOException e) {
			LoggerHelper.err(this.getClass(), "IO exception, fileName:{},reason:{}", destFileName, e.getMessage());
			throw new aaaBaseException(String.format("IO exception, fileName:%s,reason:%s", fileName, e.getMessage()));
		} finally {
			IOUtils.closeQuietly(fos);
			if (file != null) {
				file.setReadOnly();
			}
		}
	}

	private String generateDestFileName(String srcFileName) {
		Calendar now = Calendar.getInstance();
		String yyMMddHH = DateUtils.getDate2String(DateUtils.YYYYMMDD_HH, now.getTime());
		return yyMMddHH + "_" + srcFileName;
	}

	public String downloadWithMd5(String fileName, String... md5Name) throws aaaBaseException {
		String downFileFileName = download(fileName);

		String fileMd5Name = fileName + aaaConstants.MD5_EXTENSION;
		if (md5Name != null && md5Name.length > 0 && StringUtils.isNotBlank(md5Name[0])) {
			fileMd5Name = md5Name[0];
		}
		download(fileMd5Name);

		return downFileFileName;
	}
	
	public String downloadQuiet(String fileName, String... md5Name) throws aaaBaseException {
		begin();
		String downFileFileName = downloadWithMd5(fileName, md5Name);
		end();
		return downFileFileName;
	}

	/**
	 * 关闭连接
	 * 
	 * @throws aaaBaseException
	 */
	public void end() throws aaaBaseException {
		try {
			if (client.isConnected()) {
				client.logout();
			}
		} catch (IOException e) {
			LoggerHelper.err(this.getClass(), "Logout error!", e);
			throw new aaaBaseException("Logout error,reason:" + e.getMessage());
		} finally {
			if (client.isConnected()) {
				try {
					client.disconnect();
				} catch (IOException e) {
					LoggerHelper.err(this.getClass(), "Disconnect socket error!", e);
					throw new aaaBaseException("Disconnect socket error,reason:" + e.getMessage());
				}
			}
		}
	}

	/**
	 * 上传文件到ftp服务上去
	 * 
	 * @author wangye04
	 */
	public boolean upload(String filename) throws aaaBaseException {
		if (!ready) {
			throw new aaaBaseException("ftpClient isn't ready!");
		}
		String localPath = aaaConfig.getTempDir();
		if (!localPath.endsWith("/")) {
			localPath = localPath + "/";
		}
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(new File(localPath + filename));
			return client.storeFile(filename, fis);
		} catch (Exception e) {
			LoggerHelper.err(getClass(), "An exception happened, fileName:{},reason:{}", filename, e.getMessage());
			throw new aaaBaseException(e);
		} finally {
			IOUtils.closeQuietly(fis);
		}
	}
}


package com.xxx.aaa.data.ftp;

import org.apache.commons.net.ftp.FTPClientConfig;

import com.xxx.aaa.common.AAAConfig;

/**
 * ftp的配置类
 * 
 */
public class FtpClientConfig {

	/** ftp服务器地址 */
	private String server;

	/** ftp服务器端口 */
	private int port;

	/** ftp服务器用户名 */
	private String username;

	/** ftp服务器密码 */
	private String password;

	/** ftp服务器显示风格 一般为unix 或者nt */
	private String ftpStyle;

	/** 是否设置 passiveMode模式 */
	private boolean passiveMode;

	/** 是否设置以二进制传输文件 */
	private boolean binaryFileType;

	/** ftp服务器工作根目录 */
	private String rootPath;

	/** 单例,上游ftp服务 */
	private static FtpClientConfig sourceInstance = null;
	/** 单例 */
	private static FtpClientConfig targetInstance = null;

	/**
	 * 从联盟获取配置实例
	 * 
	 * @param file
	 * @return
	 */
	public static FtpClientConfig getSourceInstance() {
		if (null == sourceInstance) {
			sourceInstance = new FtpClientConfig();
			sourceInstance.initSourceConfig();
		}
		return sourceInstance;
	}

	/**
	 * 给下游系统提供服务
	 * 
	 * @return
	 */
	public static FtpClientConfig getTargetInstance() {
		if (null == targetInstance) {
			targetInstance = new FtpClientConfig();
			targetInstance.initTargetConfig();
		}
		return targetInstance;
	}

	/**
	 * 设置源ftp的属性
	 * 
	 * @throws Exception
	 */
	private void initSourceConfig() {
		setServer(AAAConfig.getConfigValueByKey("ftp.server"));
		setPort(Integer.parseInt(AAAConfig.getConfigValueByKey("ftp.port")));
		setUsername(AAAConfig.getConfigValueByKey("ftp.username"));
		setPassword(AAAConfig.getConfigValueByKey("ftp.password"));
		setFtpStyle(AAAConfig.getConfigValueByKey("ftp.ftpstyle"));
		setPassiveMode(AAAConfig.getConfigValueByKey("ftp.passivemode"));
		setBinaryFileType(AAAConfig.getConfigValueByKey("ftp.binaryfiletype"));
		setRootPath(AAAConfig.getConfigValueByKey("ftp.rootpath"));
	}

	/**
	 * 设置目标ftp的属性
	 * 
	 * @throws Exception
	 */
	private void initTargetConfig() {
		setServer(AAAConfig.getConfigValueByKey("ftp.target.server"));
		setPort(Integer.parseInt(AAAConfig.getConfigValueByKey("ftp.target.port")));
		setUsername(AAAConfig.getConfigValueByKey("ftp.target.username"));
		setPassword(AAAConfig.getConfigValueByKey("ftp.target.password"));
		setFtpStyle(AAAConfig.getConfigValueByKey("ftp.target.ftpstyle"));
		setPassiveMode(AAAConfig.getConfigValueByKey("ftp.target.passivemode"));
		setBinaryFileType(AAAConfig.getConfigValueByKey("ftp.target.binaryfiletype"));
		setRootPath(AAAConfig.getConfigValueByKey("ftp.target.rootpath"));
	}

	/**
	 * 读取二进制传输方式设置
	 * 
	 * @return
	 */
	public boolean getBinaryFileType() {
		return binaryFileType;
	}

	/**
	 * 默认以二进制形式传输文件
	 * 
	 * @param binaryFileType
	 */
	public void setBinaryFileType(String binaryFileType) {
		if (null == binaryFileType) {
			this.binaryFileType = true;
		} else {
			if ("".equals(binaryFileType.trim())) {
				this.binaryFileType = true;
			} else if ("true".equals(binaryFileType.trim())) {
				this.binaryFileType = true;
			} else if ("false".equals(binaryFileType.trim())) {
				this.binaryFileType = false;
			}
		}
	}

	public String getFtpStyle() {
		return ftpStyle;
	}

	/**
	 * 默认NT风格
	 * 
	 * @param style
	 */
	public void setFtpStyle(String style) {
		if (null == style) {
			this.ftpStyle = FTPClientConfig.SYST_NT;
		} else {
			if ("".equals(style.trim())) {
				this.ftpStyle = FTPClientConfig.SYST_NT;
			} else if ("unix".equals(style.trim())) {
				this.ftpStyle = FTPClientConfig.SYST_UNIX;
			} else if ("nt".equals(style.trim())) {
				this.ftpStyle = FTPClientConfig.SYST_NT;
			}
		}
	}

	public boolean getPassiveMode() {
		return passiveMode;
	}

	/**
	 * 默认支持passiveMode
	 * 
	 * @param passiveMode
	 */
	public void setPassiveMode(String passiveMode) {
		if (passiveMode == null) {
			this.passiveMode = true;
		} else {
			if ("".equals(passiveMode.trim())) {
				this.passiveMode = true;
			} else if ("true".equals(passiveMode.trim())) {
				this.passiveMode = true;
			} else if ("false".equals(passiveMode.trim())) {
				this.passiveMode = false;
			}
		}
	}

	public String getPassword() {
		return password;
	}

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

	public int getPort() {
		return port;
	}

	/**
	 * 默认端口为21
	 * 
	 * @param port
	 */
	public void setPort(Integer port) {
		if (null == port) {
			port = 21;
		}
		this.port = port;
	}

	public String getRootPath() {
		return rootPath;
	}

	/**
	 * 默认根目录为"/"
	 * 
	 * @param rootPath
	 */
	public void setRootPath(String rootPath) {
		if (null == rootPath) {
			rootPath = "/";
		} else {
			if ("".equals(rootPath.trim()))
				rootPath = "/";
		}
		this.rootPath = rootPath.trim();
	}

	public String getServer() {
		return server;
	}

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

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
}
分享到:
评论
1 楼 ddnzero 2016-02-21  

相关推荐

    commons-net-ftp-2.0.jar.zip

    这个库对于Java开发者来说,是进行FTP文件传输的重要工具。 FTP是一种用于在互联网上传输文件的标准协议,它的主要功能包括下载、上传文件,以及管理远程服务器上的文件。Apache Commons Net库提供了一套完整的API...

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

    2. **文件上传**:使用`FTPClient.storeFile()`方法将本地文件上传到服务器。确保设置正确的传输模式,如ASCII或二进制。 ```java InputStream inputStream = new FileInputStream("/local/file"); boolean ...

    commons-net-jar包.zip

    库提供了FTPClient、FTPSSLClient、FTPSSLSocketFactory等类,可以实现FTP的连接、登录、文件上传、下载、删除、重命名等操作,并且支持主动和被动模式,以及SSL/TLS加密。 3. **Telnet功能** Telnet协议在commons...

    commons-net-3.6

    - **FTP支持**:全面支持FTP协议,包括上传、下载、目录管理、多线程传输等功能。 - **Telnet支持**:提供了一个强大的Telnet客户端,可用于连接和交互远程服务器。 - **NNTP支持**:用于新闻组通讯,允许读取、发布...

    commons-net实现ftp帮助文档 api

    Apache Commons Net提供了丰富的类和方法,使得开发者可以方便地执行FTP任务,如上传、下载文件,创建、删除目录,以及管理文件权限等。 **FTPClient类** 是这个库中的核心,它实现了FTP协议的大部分功能。首先,你...

    commons-net-3.6.jar

    在这个版本中,我们聚焦于`commons-net-3.6.jar`,它提供了丰富的API和工具,使开发者能够方便地进行FTP文件的上传、下载以及读写操作。这个库不仅简化了FTP操作,还为开发者提供了深入理解其内部工作原理的机会,...

    commons-net-1.4.1.jar

    Apache Commons Net 1.4.1提供了一个全面的Java实现,支持FTP的各种操作,包括上传、下载、列出目录、创建和删除文件等。这个库不仅简化了FTP交互,还处理了许多底层的网络细节,如连接管理和错误处理,使得开发者...

    apache的FTP包commons-net-1.4.1.jar,jakarta-oro-2.0.8.jar

    在这个版本中,Apache Commons Net提供了对FTP协议全面的支持,包括连接到FTP服务器、上传和下载文件、创建和删除目录、改变工作目录、处理文件权限等。它的API设计得相当直观,使得开发者能够轻松地进行FTP操作。...

    commons-net-3.6 jar包.zip

    它提供了全面的FTP客户端实现,包括连接管理、文件上传、下载、列表操作、断点续传等功能。FTPClient类是FTP功能的主要接口,允许开发者通过简单的API调用来执行复杂的FTP任务。例如,你可以轻松地创建一个FTPClient...

    FTP上傳使用commons-net

    Apache Commons Net是Java库,提供了对FTP协议的全面支持,使得开发者能够轻松地在Java应用程序中实现FTP功能,包括上传、下载、删除文件等操作。在这个场景中,我们将详细探讨如何使用Apache Commons Net库进行FTP...

    apache commons-net-3.5.jar

    使用apache commons-net包实现文件ftp上传

    commons-net-ftp-2.0.rar

    这个库包含了各种FTP相关的类和方法,例如FTPClient、FTPFile、FTPSSLClient等,涵盖了FTP会话的完整生命周期,包括连接、登录、文件上传、下载、目录操作、断点续传等功能。 1. **FTPClient**: 这是Apache Commons...

    commons-net-3.1.jar,3.3,3.6版本

    - Commons Net提供了完善的FTP客户端实现,可以进行文件的上传、下载、删除等操作,支持FTP、FTPS(FTP over SSL/TLS)和SFTP(SSH File Transfer Protocol)。 - 在不同版本中,FTP客户端的性能和稳定性得到了...

    commons-net-3.3.jar

    特别是对于FTP,它不仅支持基本的文件上传和下载,还包含如文件重命名、目录管理、断点续传等功能。 二、FTPClient模块 在`commons-net-3.3.jar`中,FTPClient类是核心,它实现了完整的FTP协议。开发者可以通过创建...

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

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

    commons-net-3.3-3.4-3.5-3.6.zip

    总结起来,Apache Commons Net库是实现Android FTP文件上传功能的重要工具,它提供了丰富的API和功能,可以方便地集成到Android项目中。通过合理选择和使用这个库的不同版本,开发者可以高效地完成FTP交互任务。

    jar包-commons-net-3.3.jar

    由于这里只有一个文件,即"commons-net-3.3.jar",我们可以推断这可能是一个单一的JAR文件下载,而不是一个包含多个文件的压缩包。这个JAR文件包含了Apache Commons Net库的所有类和资源,可以直接被Java项目引用和...

    commons-net-3.2

    例如,通过FTPClient类,只需几行代码就可以实现文件的上传和下载。同时,由于库中的类和方法设计良好,可读性强,使得维护和扩展代码变得容易。 总结来说,Apache Commons Net 3.2是一个强大的Java网络库,提供了...

    commons-net-1.4.1.jar功能实现demo

    描述提到的是一个具体的示例程序——"FTPDemo",这是一个基于`commons-net-1.4.1.jar`的Java应用,演示了如何使用该库来与FTP服务器进行交互,实现了文件的上传和下载功能。在MyEclipse这样的集成开发环境中,这个...

Global site tag (gtag.js) - Google Analytics