ftp工具类

package com.ytd.zjdlbb.service.zjdlbb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
*******************************************************************************
* 文件名称:FTPService.java 系统名称: 类 概 述: FTP文件上传下载 创建日期:2015年4月3日 下午5:17:52 版 本:
* V1.0.0
*******************************************************************************
*/
public class FTPService {
private Logger log = Logger.getLogger(getClass());
protected static String FTP_CONTROL_ENCODING = "ISO-8859-1";
protected static String FTP_CHARSET_NAME;
protected static String FTP_SYSTEM_TYPE;
protected static String LOCAL_FILE_ENCODING = System.getProperty("file.encoding");
protected static String LOCAL_SYSTEM_TYPE = System.getProperty("os.name");
public static String FTP_CONTROL_ENCODING_LOCAL = "GBK";

/**
* @Description 概要说明:上传文件到FTP服务器
*
* @date 2015年4月6日 下午4:12:51
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param port
* 端口
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* FTP保存文件的目录
* @param localFile
* 本地需要上传的文件
* @return boolean
*/
public boolean upload(String ip, int port, String username, String pwd, String remoteDir, String localFile) {
File in = new File(localFile);
return upload(ip, port, username, pwd, remoteDir, in);
}

/**
* @Description 概要说明:上传文件到FTP服务器
*
* @date 2015年4月6日 下午4:12:51
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* FTP保存文件的目录
* @param localFile
* 本地需要上传的文件
* @return boolean
*/
public boolean upload(String ip, String username, String pwd, String remoteDir, String localFile) {
File in = new File(localFile);
return upload(ip, username, pwd, remoteDir, in);
}

/**
* @Description 概要说明:上传文件到FTP服务器
*
* @date 2015年4月6日 下午4:12:51
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param port
* 端口
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* FTP保存文件的目录
* @param in
* 本地需要上传的文件
* @return boolean
*/
public boolean upload(String ip, int port, String username, String pwd, String remoteDir, File in) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
// 建立连接、登录
success = login(ftp, ip, username, pwd);
if (!success) {
return success;
}
uploadFile(ftp, remoteDir, in);
// 退出登录
ftp.logout();
success = true;
} catch (IOException e) {
log.error("", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}

/**
* @Description 概要说明:上传文件到FTP服务器
*
* @date 2015年4月6日 下午4:12:51
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* FTP保存文件的目录
* @param in
* 本地需要上传的文件
* @return boolean
*/
public boolean upload(String ip, String username, String pwd, String remoteDir, File in) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
// 建立连接、登录
success = login(ftp, ip, username, pwd);
if (!success) {
return success;
}
uploadFile(ftp, remoteDir, in);
// 退出登录
ftp.logout();
success = true;
} catch (IOException e) {
log.error("", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}

/**
* @Description 概要说明:本地文件上传到FTP指定目录
*
* @date 2015年4月6日 下午4:16:10
* @update xxx(yyyy-MM-dd)
* @param ftp
* FTP对象
* @param remoteDir
* FTP目录
* @param in
* 本地文件
* @return void
* @throws IOException
*/
public void uploadFile(FTPClient ftp, String remoteDir, File in) throws IOException {
String fileName = in.getName();
try {
if (!in.exists()) {
throw new IOException("文件[" + fileName + "]不存在!");
} else {
if (in.isDirectory()) {
remoteDir = remoteDir + "/" + fileName;
ftp.makeDirectory(local2Remote_encoding(remoteDir));
File[] files = in.listFiles();
for (File tmp : files) {
uploadFile(ftp, remoteDir, tmp);
}
} else {
uploadFile(ftp, remoteDir, fileName, in);
}
}
log.info("[" + fileName + "/" + in.length() / 1024 + "KB]上传成功!");
} catch (IOException e) {
log.info("[" + fileName + "]上传失败!");
throw e;
}
}

/**
* @Description 概要说明:文件上传
*
* @date 2015年4月6日 下午4:54:21
* @update xxx(yyyy-MM-dd)
* @param ftp
* @param remoteDir
* @param fileName
* @param in
* @throws IOException
* void
*/
public void uploadFile(FTPClient ftp, String remoteDir, String fileName, File in) throws IOException {
remoteDir = local2Remote_encoding(remoteDir + "/");
ftp.changeWorkingDirectory(remoteDir);
fileName = local2Remote_encoding(fileName);
InputStream input = null;
try {
log.debug("localFile:" + in.getAbsolutePath());
input = new FileInputStream(in);
boolean isSucc = ftp.storeFile(fileName, input);
if (!isSucc) {
throw new IOException("文件[" + fileName + "/" + (in.getTotalSpace() / 1024) + "Kb]上传失败!");
}
} catch (IOException e) {
throw e;
} finally {
input.close();
}
}

/**
* @Description 概要说明:从FTP上下载文件
*
* @date 2015年4月3日 下午10:53:43
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* 需要下载的目标目录
* @param localDir
* 本地保存目录
* @return boolean
*/
public List<File> download(String ip, String username, String pwd, String remoteDir, String localDir) {
boolean success = false;
FTPClient ftp = new FTPClient();
List<File> list = null;
try {
// 建立连接、登录
success = login(ftp, ip, username, pwd);
if (!success) {
return list;
}
list = downloadFile(ftp, remoteDir, localDir);
// 退出登录
ftp.logout();
} catch (IOException e) {
log.error("", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return list;
}

/**
* @Description 概要说明:从FTP服务器上下载文件
*
* @date 2015年4月3日 下午10:46:05
* @update xxx(yyyy-MM-dd)
* @param ip
* FTP服务器IP地址
* @param port
* 端口号
* @param username
* 用户名
* @param pwd
* 密码
* @param remoteDir
* 需要下载的目标目录
* @param localDir
* 本地保存目录
* @return boolean
*/
public List<File> download(String ip, int port, String username, String pwd, String remoteDir, String localDir) {
boolean success = false;
FTPClient ftp = new FTPClient();
List<File> list = null;
try {
success = login(ftp, ip, port, username, pwd);
if (!success) {
return list;
}
list = downloadFile(ftp, remoteDir, localDir);
ftp.logout();
} catch (IOException e) {
log.error("", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return list;
}

/**
* @Description 概要说明:过滤本目录以及父级目录
*
* @date 2015年4月4日 上午12:00:15
* @update xxx(yyyy-MM-dd)
* @param fs
* @return List<FTPFile>
*/
protected List<FTPFile> filterSelf(FTPClient ftp, FTPFile[] fs) throws UnsupportedEncodingException {
List<FTPFile> list = new ArrayList<FTPFile>();
for (FTPFile tmp : fs) {
String tmpName = tmp.getName();
Pattern p1 = Pattern.compile("^\.$");
Matcher m1 = p1.matcher(tmpName);
Pattern p2 = Pattern.compile("^\.\.$");
Matcher m2 = p2.matcher(tmpName);
boolean self1 = m1.find();
boolean self2 = m2.find();
if (!self1 && !self2) {
list.add(tmp);
}
}
return list;
}

/**
* @Description 概要说明:文件过滤逻辑,重写自定义逻辑
*
* @date 2015年4月3日 下午10:38:03
* @update xxx(yyyy-MM-dd)
* @param fs
* @return List<FTPFile>
*/
protected List<FTPFile> filter(FTPClient ftp, List<FTPFile> fs, Object... params) {
List<FTPFile> files = new ArrayList<FTPFile>();
List<FTPFile> dirs = new ArrayList<FTPFile>();
for (FTPFile tmp : fs) {
if (tmp.isDirectory()) {
dirs.add(tmp);
} else {
files.add(tmp);
}
}
files.addAll(dirs);
return files;
}

/**
* @Description 概要说明:下载文件到本地
*
* @date 2015年4月3日 下午5:22:18
* @update xxx(yyyy-MM-dd)
* @param ftp
* ftp对象
* @param files
* 远程主机文件集合
* @param localDir
* 需要下载到本地目录
* @throws IOException
* void
*/
public List<File> downloadFile(FTPClient ftp, String remoteDir, String localDir) throws IOException {
String tmpRemote = local2Remote_encoding(remoteDir);
ftp.changeWorkingDirectory("~");
ftp.changeWorkingDirectory(tmpRemote);
FTPFile[] fs = ftp.listFiles();
List<File> list = new ArrayList<File>();
// 过滤文件
List<FTPFile> files = filter(ftp, filterSelf(ftp, fs));
// 递归下载
for (FTPFile file : files) {
try {
String tmpName = file.getName();
if (file.isDirectory()) {
String remoteTmpDir = remoteDir + "/" + tmpName + "/";
String localTmpDir = localDir + "/" + tmpName + "/";
File localTmpFile = new File(localTmpDir);
if (localTmpFile.exists()) {
if (!localTmpFile.isDirectory()) {
throw new IOException("文件[" + localTmpFile.getName() + "]不是目录!");
}
} else {
localTmpFile.mkdirs();
}
list.addAll(downloadFile(ftp, remoteTmpDir, localTmpDir));
} else {
File f = downloadFile(ftp, file, remoteDir, localDir);
if (f != null) {
list.add(f);
log.info("文件[" + file.getName() + "/" + file.getSize() / (1024) + "KB]下载成功!");
}
}
} catch (IOException e) {
log.info("文件[" + file.getName() + "]下载失败!");
throw e;
}
}

return list;
}

/**
* @Description 概要说明:下载文件到本地
*
* @date 2015年4月3日 下午5:21:30
* @update xxx(yyyy-MM-dd)
* @param ftp
* ftp对象
* @param file
* 远程主机文件
* @param localDir
* 需要下载到本地目录
* @throws IOException
* void
*/
public File downloadFile(FTPClient ftp, FTPFile file, String remoteDir, String localDir) throws IOException {
String tmpName = file.getName();
ftp.changeWorkingDirectory("~");
remoteDir = local2Remote_encoding(remoteDir);
ftp.changeWorkingDirectory(remoteDir);
File localFile = new File(localDir + File.separator + tmpName);
tmpName = local2Remote_encoding(tmpName);
OutputStream os = null;
boolean isSucc = false;
try {
log.debug("localFile:" + localFile.getAbsoluteFile());
os = new FileOutputStream(localFile);
isSucc = ftp.retrieveFile(tmpName, os);
if (isSucc) {
return localFile;
}/*
* else{ try { InputStream in =
* ftp.retrieveFileStream("/"+remoteDir+"/"+tmpName); int len = -1;
* byte[] readB = new byte[1024]; while ((len = in.read(readB)) !=
* -1) { os.write(readB, 0, len); os.flush(); } isSucc = true;
* return localFile; } catch (IOException e) { throw e; } }
*/
return null;
} catch (IOException e) {
throw e;
} finally {
os.close();
if (!isSucc && localFile.exists()) {
log.warn("文件[" + tmpName + "/" + (file.getSize() / 1024) + "Kb]下载失败!");
localFile.delete();
}
}
}

/**
* @Description 概要说明:登录FTP
*
* @date 2015年4月3日 下午5:22:44
* @update xxx(yyyy-MM-dd)
* @param ftp
* FTP对象
* @param ip
* FTP主机IP地址
* @param port
* 端口
* @param username
* 用户名
* @param pwd
* 密码
* @return
* @throws SocketException
* @throws IOException
* boolean
*/
protected boolean login(FTPClient ftp, String ip, int port, String username, String pwd) throws SocketException, IOException {
ftp.connect(ip, port);
ftp.login(username, pwd);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return false;
}
log.info("FTP Server IP:" + ip);
log.info("FTP Server User:" + username + " login success.");
reply = ftp.sendCommand("OPTS UTF8", "ON");
if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
FTP_CONTROL_ENCODING_LOCAL = "UTF-8";
}

FTP_SYSTEM_TYPE = ftp.getSystemType();
FTP_CHARSET_NAME = ftp.getCharsetName();
FTP_CONTROL_ENCODING = ftp.getControlEncoding();

// 解决文件名乱码问题
ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL);
ftp.enterLocalPassiveMode();// 设置被动模式
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式

return true;
}

/**
* @Description 概要说明:登录FTP
*
* @date 2015年4月3日 下午5:23:25
* @update xxx(yyyy-MM-dd)
* @param ftp
* FTP对象
* @param ip
* FTP主机IP地址
* @param username
* 用户名
* @param pwd
* 密码
* @return
* @throws SocketException
* @throws IOException
* boolean
*/
protected boolean login(FTPClient ftp, String ip, String username, String pwd) throws SocketException, IOException {
ftp.connect(ip);
ftp.login(username, pwd);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return false;
}
log.info("FTP Server IP:" + ip);
log.info("FTP Server User:" + username + " login success.");
reply = ftp.sendCommand("OPTS UTF8", "ON");
if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
FTP_CONTROL_ENCODING_LOCAL = "UTF-8";
}

FTP_SYSTEM_TYPE = ftp.getSystemType();
FTP_CHARSET_NAME = ftp.getCharsetName();
FTP_CONTROL_ENCODING = ftp.getControlEncoding();

// 解决文件名乱码问题
ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL);
ftp.enterLocalPassiveMode();// 设置被动模式
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式

return true;
}

public String remote2Local_encoding(String remote) {
String result = null;
try {
result = new String(remote.getBytes(FTP_CONTROL_ENCODING), FTP_CONTROL_ENCODING_LOCAL);
} catch (UnsupportedEncodingException e) {
log.error("", e);
}
return result;
}

public String local2Remote_encoding(String local) {
String result = null;
try {
result = new String(local.getBytes(FTP_CONTROL_ENCODING_LOCAL), FTP_CONTROL_ENCODING);
} catch (UnsupportedEncodingException e) {
log.error("", e);
}
return result;
}

public String sys2Local_encoding(String sys) {
String result = null;
try {
result = new String(sys.getBytes(), FTP_CONTROL_ENCODING_LOCAL);
} catch (UnsupportedEncodingException e) {
log.error("", e);
}
return result;
}

public String sys2Remote_encoding(String sys) {
String result = null;
try {
result = new String(sys.getBytes(), FTP_CONTROL_ENCODING);
} catch (UnsupportedEncodingException e) {
log.error("", e);
}
return result;
}

/**
* @Description 概要说明:是否最新文件
*
* @date 2016年1月20日 下午3:49:47
* @update xxx(yyyy-MM-dd)
* @param ftp
* @param file
* @param remoteDir
* @return
* @throws IOException
* boolean
*/
public boolean isLast(FTPClient ftp, FTPFile file, String remoteDir) throws IOException {
String tmpRemote = local2Remote_encoding(remoteDir);
ftp.changeWorkingDirectory("~");
ftp.changeWorkingDirectory(tmpRemote);
FTPFile[] ftpFiles = ftp.listFiles();
List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles));
long lastTime = 0;
FTPFile tmpFile = null;
for (FTPFile ftpFile : files) {
long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis();
if (tmpLastTime > lastTime) {
lastTime = tmpLastTime;
tmpFile = ftpFile;
}
}

return tmpFile == null ? false : file.getName().equals(tmpFile.getName());
}

/**
* @Description 概要说明:匹配结束字符文件
* @date 2016年1月20日 下午3:49:47
* @update xxx(yyyy-MM-dd)
* @param file
* FTP文件对象
* @param end
* 结束字符
* @return
* @throws IOException
* boolean
*/
public boolean endWith(FTPFile file, String end) throws IOException {
if (null == end) {
end = "";
}
return file.getName().endsWith(end);
}

public boolean isLastAndEndWith(FTPClient ftp, FTPFile file, String remoteDir, String end) throws IOException {
if (file.getName().endsWith(end)) {
String tmpRemote = local2Remote_encoding(remoteDir);
ftp.changeWorkingDirectory("~");
ftp.changeWorkingDirectory(tmpRemote);
FTPFile[] ftpFiles = ftp.listFiles();
List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles));
long lastTime = 0;
FTPFile tmpFile = null;
for (FTPFile ftpFile : files) {
long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis();
if (ftpFile.getName().endsWith(end) && tmpLastTime > lastTime) {
lastTime = tmpLastTime;
tmpFile = ftpFile;
}
}

return tmpFile == null ? false : file.getName().equals(tmpFile.getName());
}

return false;
}

public static void main(String args[]) {
FTPService ftp = new FTPService();
String ip = "127.0.0.1";
int port = 1111;
String username = "crd";
String pwd = "crd";
String remoteDir = "";
String localDir = "C:/Users/Administrator/Desktop/test";
ftp.download(ip, port, username, pwd, remoteDir, localDir);
System.out.println(122);
}

}

原文地址:https://www.cnblogs.com/rdchen/p/10175876.html