java使用apache.commons.net.ftp工具实现FTP文件上传下载
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileFilter;
import org.apache.commons.net.ftp.FTPReply;
/**
*
*
* <pre>
* _________________________INFO_____________________________
* | Description : [采用apache的工具包进行ftp传输|下载暂不支持AIX系统]
* | Encoding : [UTF-8]
* | Package : [org.xqlee.utils.ftp]
* | Project : [utils]
* | Author : [LXQ]
* | CreateDate : [2016年5月2日上午11:12:52]
* | Updater : []
* | UpdateDate : []
* | UpdateRemark: []
* | Company : [Shallink Electronic Information]
* | Version : [v 1.0]
* | Libs : [commons-net-3.3.jar]
* __________________________________________________________
* </pre>
*/
public class FTPUtil {
/** FTP端口 **/
private int port = 0;
/** FTP主机名或者IP **/
private String host = "";
/** FTP用户名称 ***/
private String userName = "";
/** FTP用户密码 **/
private String userPassword = "";
/** 本地字符集编码 **/
private String encoding = "utf-8";
/**
* 调用前必须配置ftp链接参数
*
* @param port
* 链接端口号
* @param host
* 链接主机名或者IP/域名
* @param userName
* ftp用户名
* @param userPassword
* ftp密码
* @param localEncoding
* 本地字符集编码(默认null将设置为utf-8)
*/
public void setConfig(int port, String host, String userName, String userPassword, String encoding) {
this.port = port;
this.host = host;
this.userName = userName;
this.userPassword = userPassword;
if (null != encoding && !"".equals(encoding)) {
this.encoding = encoding;
}
}
public FTPClient connectFTPServer() throws SocketException, IOException {
// 实例化一个ftp客户端
FTPClient ftpClient = new FTPClient();
// 连接服务器
log("HOST:" + host + " Port:" + port);
ftpClient.connect(host, port);
boolean isLogin = ftpClient.login(userName, userPassword);
if (!isLogin) {
throw new IOException("Login Ftp Server Fail,Plase Check Port,Host,user,password is all Rigth?");
} else {
log("Login Ftp Server Success!");
}
log("FTP Server Type:[" + ftpClient.getSystemType() + "]");
return ftpClient;
}
/**
* 向ftp写文件(数据)
*
* @throws IOException
* @throws SocketException
*/
public void upload(String srcFile, String destFile) throws SocketException, IOException {
// 替换源文件和目标文件中的反斜杠
srcFile = srcFile.replaceAll("\\\\", "/");
destFile = destFile.replaceAll("\\\\", "/");
// 文件路径处理,以便支持中文
srcFile = new String(srcFile.getBytes(encoding), "iso-8859-1");
destFile = new String(destFile.getBytes(encoding), "iso-8859-1");
FTPClient ftpClient = null;
// 创建本机源文件
File src = new File(srcFile);
// 转换文件输入流
FileInputStream fis = new FileInputStream(src);
// 获取ftpClient实例
ftpClient = connectFTPServer();
// 远程目录
String destPath = destFile.substring(0, destFile.lastIndexOf("/"));
// 判断文件目录是否存在
if (!ftpClient.changeWorkingDirectory(destPath)) {
// 不存在创建
ftpClient.makeDirectory(destPath);
}
// 指定写入的目录
ftpClient.changeWorkingDirectory(destPath);
// 写操作/采用二进制方式传输
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 文件名
String fn = new String(src.getName().getBytes(encoding), "iso-8859-1");
// 文件全路径
String ffn = destPath + fn;
// 执行传输[参数1:新文件名称;参数2:本地文件的输入流][注意]文件路径最好使用全路径否则可能发生空文件情况
boolean us = ftpClient.storeFile(ffn, fis);
if (us) {
log("File [" + ffn + "] Upload Success!");
} else {
throw new IOException("File [" + ffn + "] Upload Fail!");
}
// 关闭文件输入流/退出登录/断开连接
fis.close();
boolean b = ftpClient.logout();
if (b) {
log("Logout Ftp Server Success!");
} else {
log("Logout Ftp Server Fail!");
}
ftpClient.disconnect();
}
/**
* 上传文件到指定目录
*
* @param files
* 待上传的文件数组
* @param targetPath
* 远程短文件路径
* @throws IOException
* 可能发生的异常
*/
public void upload(File files[], String targetPath) throws IOException {
for (int i = 0; i < files.length; i++) {
if (!files[i].exists()) {
throw new IOException("File Not Found![" + files[i].getAbsolutePath() + "]");
}
}
// 对上传目标路径进行两次编码,进行中文的支持
targetPath = new String(targetPath.getBytes(encoding), "iso-8859-1");
FTPClient ftpClient = null;
// 获取ftpClient实例
ftpClient = connectFTPServer();
// 判断文件目录是否存在
if (!ftpClient.changeWorkingDirectory(targetPath)) {
// 不存在创建
ftpClient.makeDirectory(targetPath);
}
// 指定写入的目录
ftpClient.changeWorkingDirectory(targetPath);
// 写操作/采用二进制方式传输
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 循环写入文件
BufferedInputStream bis = null;
int count = 0;
for (int i = 0; i < files.length; i++) {
bis = new BufferedInputStream(new FileInputStream(files[i]));
// 避免发生空文件,使用全路径上传
String tn = files[i].getName() + ".tmp";
tn = new String(tn.getBytes(encoding), "iso-8859-1");
String tmpFileName = targetPath + tn;
String fn = files[i].getName();
fn = new String(fn.getBytes(encoding), "iso-8859-1");
String fileName = targetPath + fn;
// 1.先上传到临时文件
boolean us = ftpClient.storeFile(tmpFileName, bis);
if (us) {
log("File [" + new String(tmpFileName.getBytes("iso-8859-1"), encoding) + "] Upload Success!");
} else {
log("File [" + new String(tmpFileName.getBytes("iso-8859-1"), encoding) + "] Upload Fail!");
}
// 2.更名为目标文件
boolean rs = ftpClient.rename(tmpFileName, fileName);
if (rs) {
log("File [" + new String(fileName.getBytes("iso-8859-1"), encoding) + "] mv Success!");
count++;
} else {
log("File [" + new String(fileName.getBytes("iso-8859-1"), encoding) + "] mv Fail!");
}
}
log("File Total [" + files.length + "] Transfer Success[" + count + "]");
// 关闭文件输入流/退出登录/断开连接
if (bis != null) {
bis.close();
}
boolean b = ftpClient.logout();
if (b) {
log("Logout Ftp Server Success!");
} else {
log("Logout Ftp Server Fail!");
}
ftpClient.disconnect();
}
/**
* 下载FTP服务器文件到本地路径
*
* @param SRCPATH
* FTP服务器文件路径
* @param DESTPATH
* 本地存放路径
* @param fileFilter
* 文件名称过滤,不使用填写NULL
* @throws IOException
* 下载过程中可能出现的IO异常
*/
public void download(String SRCPATH, String DESTPATH, FTPFileFilter fileFilter) throws IOException {
download(SRCPATH, DESTPATH, false, false, null, fileFilter);
}
/**
* 下载FTP服务器文件到本地,可选择删除下载后的文件[需要用户权限]
*
* @param SRCPATH
* 源文件路径地址
* @param DESTPATH
* 下载到本地的路径地址
* @param isDelSrc
* 是否删除源文件
* @param fileFilter
* 文件名称过滤,不使用填写NULL
* @throws IOException
* 下载过程中可能出现的异常
*/
public void download(String SRCPATH, String DESTPATH, boolean isDelSrc, FTPFileFilter fileFilter)
throws IOException {
download(SRCPATH, DESTPATH, isDelSrc, false, null, fileFilter);
}
/**
* 从FTP下载文件,并提供备份文件到另外一个目录[备份需要权限]
*
* @param SRCPATH
* 原文件目录
* @param DESTPATH
* 目标文件目录
* @param isBackupTo
* 是否移动备份
* @param backupPath
* 备份目录
* @param fileFilter
* 文件名称过滤,不使用填写NULL
* @throws IOException
* 下载过程中可能出现的IO异常
*/
public void download(String SRCPATH, String DESTPATH, boolean isBackupTo, String backupPath,
FTPFileFilter fileFilter) throws IOException {
download(SRCPATH, DESTPATH, false, isBackupTo, backupPath, fileFilter);
}
/**
* FTP 下载文件
*
* @param SRCPATH
* 源文件路径
* @param DESTPATH
* 下载到本地路径
* @param isDelSrc
* 下载后是否删除源文件
* @param isBackupTo
* 是否将下载后的文件移动备份到其他地方
* @param backupPath
* [当备份为true时]备份移动的目录
* @throws IOException
*/
protected void download(String SRCPATH, String DESTPATH, boolean isDelSrc, boolean isBackupTo, String backupPath,
FTPFileFilter fileFilter) throws IOException {
// 替换路径中的反斜杠
SRCPATH = SRCPATH.replace("\\\\", "/");
DESTPATH = DESTPATH.replace("\\\\", "/");
backupPath = backupPath.replace("\\\\", "/");
// 路径处理以便支持中文
SRCPATH = new String(SRCPATH.getBytes(encoding), "iso-8859-1");
DESTPATH = new String(DESTPATH.getBytes(encoding), "iso-8859-1");
backupPath = new String(backupPath.getBytes(encoding), "iso-8859-1");
// 处理路径
if (!SRCPATH.endsWith("/")) {
SRCPATH = SRCPATH + "/";
}
if (DESTPATH.endsWith("/")) {
DESTPATH = DESTPATH + "/";
}
if (backupPath.endsWith("/")) {
backupPath = backupPath + "/";
}
// 链接ftp
FTPClient ftp = connectFTPServer();
// 判断是否登陆成功
int reply;
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
throw new IOException("=======MISS LOGIN,CONNECT DISCONNECT...======");
}
// 判断文件目录是否存在
if (!ftp.changeWorkingDirectory(SRCPATH)) {
// 不存在创建
ftp.makeDirectory(SRCPATH);
}
ftp.changeWorkingDirectory(SRCPATH);// 转移到FTP服务器目录
// 遍历下载的目录
FTPFile[] fs = null;
if (null == fileFilter) {
fs = ftp.listFiles();
} else {
fs = ftp.listFiles(SRCPATH, fileFilter);
}
for (FTPFile ff : fs) {
if (ff.isFile()) {
// 解决中文乱码问题,两次解码
String fn = new String(ff.getName().getBytes(encoding), "iso-8859-1");
// =======判断本地文件目录是否存在,不存在创建=======
File localPath = new File(DESTPATH);
if (!localPath.exists()) {
localPath.mkdirs();
} else {
if (localPath.isFile()) {
localPath.delete();
localPath.mkdirs();
}
}
// =======处理文件名=======
String localFileName = DESTPATH + fn;
File localFile = new File(localFileName);
String tmpFileName = DESTPATH + fn + ".tmp";
String srcFileName = SRCPATH + fn;
// 写操作,将其写入到本地文件中
File tempFile = new File(tmpFileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile));
// 使用全路径,防止空文件
ftp.retrieveFile(srcFileName, bos);
bos.close();
// 下载完成更名本地
tempFile.renameTo(localFile);
// =======下载完成后,后续操作=======
// 判断是否备份
if (isBackupTo) {
// 判断备份目录是否存在,不存在创建
if (!ftp.changeWorkingDirectory(backupPath)) {
// 不存在创建
ftp.makeDirectory(backupPath);
}
// 执行备份移动
boolean bk = ftp.rename(SRCPATH + "/" + fn, backupPath + "/" + fn);
if (bk) {
log("Backup Ftp File to [" + new String((backupPath + fn).getBytes("iso-8859-1"), encoding)
+ "]Success !");
} else {
log("Backup Ftp File to [" + new String((backupPath + fn).getBytes("iso-8859-1"), encoding)
+ "]Fail !");
}
} else {
// 判断是否删除下载后的源文件
if (isDelSrc) {
boolean del = ftp.deleteFile(SRCPATH + "/" + fn);
if (del) {
log("Delete Source File[" + new String((SRCPATH + fn).getBytes("iso-8859-1"), encoding)
+ "] Success!");
} else {
log("Delete Source File[" + new String((SRCPATH + fn).getBytes("iso-8859-1"), encoding)
+ "] Fail!");
}
}
}
} else {
// 迭代处理文件目录
String dn = new String(ff.getName().getBytes(encoding), "iso-8859-1");
download(SRCPATH + dn, DESTPATH + dn, isDelSrc, isBackupTo, backupPath + dn, fileFilter);
}
}
boolean b = ftp.logout();
if (b) {
log("Logout Ftp Server Success!");
} else {
log("Logout Ftp Server Fail!");
}
ftp.disconnect();
}
/**
* 日志打印处理
*
* @param msg
* 信息
*/
public void log(String msg) {
String time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
msg = time + " - " + msg;
System.out.println(msg);
}
}
http://blog.xqlee.com/article/7.html