基于Apache的commons-net-3.3.jar
代码中涉及一些自定义的类,不过基本都顾名思义。稍作修改即可使用。流程没问题,中文不乱码。
package indi.jyw.common.util;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FtpTool {
/**
* 调测日志记录器。
*/
private static final Logger DEBUGGER = LoggerFactory.getLogger(FtpTool.class);
private FTPClient ftpClient = null;
public FtpTool() {
this.ftpClient = new FTPClient();
}
public void login(int port, String host, String username, String password) throws FtpException {
boolean success = false;
String msg = null;
int reply;
try {
if (port > -1) {
ftpClient.connect(host, port);
} else {
ftpClient.connect(host);
}
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
}
ftpClient.setConnectTimeout(0);
// set timeout to 5 minutes
ftpClient.setControlKeepAliveTimeout(300);
// 设置以字节流传输模式
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
// 设置为被动模式登陆
ftpClient.enterLocalPassiveMode();
ftpClient.setAutodetectUTF8(true);
// 保存FTP控制连接使用的字符集,必须在连接前设置
ftpClient.setControlEncoding("UTF-8");
if (ftpClient.login(username, password)) {
success = true;
// 设置文件类型,必须在login后
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
} else {
success = false;
msg = "登录失败,请检查用户名密码!";
}
} catch (IOException e) {
DEBUGGER.error("登录异常", e);
msg = "登录异常";
}
if (!success) {
throw new FtpException(msg);
}
}
/**
* 登出和断开连接的方法
*/
public void logoutAndDisconnect() {
try {
ftpClient.logout();
} catch (IOException e) {
DEBUGGER.error("Failed to logout", e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
DEBUGGER.error("Failed to disconnect", e);
}
}
}
}
/**
* 切换到对应目录,失败直接抛出异常
*
* @param remoteDir
* @throws FtpException
*/
public void changeDir(String remoteDir) throws FtpException {
boolean res;
String msg = null;
try {
res = ftpClient.changeWorkingDirectory(remoteDir);
if (!res) {
msg = "FTP远程目录不存在 :" + remoteDir;
}
} catch (IOException e) {
DEBUGGER.error("Failed to changeDir", e);
res = false;
msg = "切换至对应目录异常";
}
if (!res) {
throw new FtpException(msg);
}
}
/**
* ftp上传
*
* @param ftpClient
* @param uploadBean
* @return 上传成功的文件 返回文件的完整路径
*/
public List<String> uploadFile(FileUploadBean uploadBean, List<InvLogFileupload> logList) {
if (uploadBean == null) {
return null;
}
List<File> fileList = uploadBean.getUploadFiles();
List<String> uploadFile = new ArrayList<String>(10);
if (fileList.isEmpty()) {
return null;
}
for (File file : fileList) {
uploadSingleFile(uploadBean, logList, uploadFile, file);
}
return uploadFile;
}
/**
* 处理单个文件的上传
*/
private void uploadSingleFile(FileUploadBean uploadBean, List log, List uploadFile, File file) {
FileInputStream in = null;
InvLogFileupload logBean = new InvLogFileupload();
logBean.setUploadid(uploadBean.getUploadid());
logBean.setStarttime(DateUtils.getCurrentDate());
logBean.setFilename(file.getName());
try {
in = new FileInputStream(file);
String fileName = new String(file.getName().getBytes("UTF-8"), "ISO-8859-1");
if (ftpClient.storeFile(fileName, in)) {
uploadFile.add(file.getPath());
logBean.setStatus("1");
logBean.setStatusdesc("上传成功");
} else {
logBean.setStatus("0");
logBean.setStatusdesc("上传失败");
}
} catch (FileNotFoundException e) {
DEBUGGER.error("Failed to uploadSingleFile", e);
} catch (IOException e) {
DEBUGGER.error("Failed to uploadSingleFile", e);
} finally {
IOUtil.closeQuietly(in);
}
logBean.setLogid(Sequence.generateSeqByTable("JYW_LOG_FILEUPLOAD"));
logBean.setEndtime(DateUtils.getCurrentDate());
log.add(logBean);
}
/**
* 列出FTP当前目录的文件,同时进行文件的筛选过滤
*
* @param taskType
* @param workDir
* @param lff
* @return
* @throws IOException
*/
public List<String> listFtpDirectory(String taskType, String workDir, List<String> lff) throws IOException {
FTPFile[] fs = ftpClient.listFiles(workDir);
for (FTPFile ff : fs) {
// 跳过当前目录和上级目录
if ((".".equals(ff.getName())) || ("..".equals(ff.getName()))) {
continue;
}
if (ff.isDirectory()) {
continue;
} else {
String fName = ff.getName();
// 筛选文件的方法
if (FileUtil.isFileNameMatchTaskType(taskType, fName, workDir)) {
lff.add(workDir + "/" + ff.getName());
}
}
}
return lff;
}
/**
* ftp单个文件下载,异常直接内部处理,尽量不影响后续文件的下载
*
* @param remoteFilePath
* @param tempFile
* @param logBean
* @return 是否下载成功
*/
public boolean downloadFile(String remoteFilePath, File tempFile, InvLogDownloadfile logBean) {
OutputStream is = null;
boolean isSuccess;
// 单个文件下载产生的异常直接处理,不影响其他文件的下载
try {
is = new FileOutputStream(tempFile);
remoteFilePath = new String(remoteFilePath.getBytes("utf-8"), "iso-8859-1");
isSuccess = ftpClient.retrieveFile(remoteFilePath, is);
} catch (IOException e) {
DEBUGGER.error("Failed to downloadFile", e);
isSuccess = false;
} finally {
logBean.setEndtime(DateUtils.getCurrentDate());
IOUtil.closeQuietly(is);
}
if (isSuccess) {
logBean.setStatus(FtpConstants.DOWNLOAD_LOG_SUCC);
logBean.setStatusdesc("下载成功");
// 删除文件失败出现异常直接处理 依然算下载成功
try {
ftpClient.deleteFile(remoteFilePath);
} catch (IOException e) {
logBean.setStatusdesc("下载成功,远端文件删除失败");
DEBUGGER.error("下载成功,远端文件删除失败:" + remoteFilePath, e);
}
} else {
logBean.setStatus(FtpConstants.DOWNLOAD_LOG_FAIL);
logBean.setStatusdesc("下载失败");
}
return isSuccess;
}
private void downloadFile(FtpTool ftp, InvFileDownloadtask config, List logList) throws FtpException {
// 列出文件,返回的是完整的目录,而不只是文件名
List fs = new ArrayList();
try {
ftp.listFtpDirectory(config.getTasktype(), config.getRemotedir(), fs);
} catch (IOException e) {
DEBUGGER.error("Failed to downloadFile", e);
throw new FtpException("列出远程目录文件异常");
}
if (fs.isEmpty()) {
return;
}
String localPath = config.getLocaldir();
String localTempPath = localPath + File.separator + "temp";
List downloadFileList = new ArrayList();
String fileName;
File tempFile;
// 下载文件至临时目录
for (String remoteFilePath : fs) {
fileName = FileUtil.getFileName(remoteFilePath, "/");
InvLogDownloadfile logBean = getNewLog(config, "", fileName);
logList.add(logBean);
// 如果文件已下载则删除此文件 modi:此处不再校验是否下载过
/*
* if (dao.isAlreadyDownload(config, fileName)) {
* HandleDownloadedFile(remoteFilePath, logBean); }
*/
// 临时文件
tempFile = new File(localTempPath, fileName);
FileUtil.createNewFile(tempFile);
if (ftp.downloadFile(remoteFilePath, tempFile, logBean)) {
downloadFileList.add(tempFile);
DEBUGGER.info("File :" + fileName + " 下载成功 ");
} else {
DEBUGGER.info("File :" + fileName + " 下载失败 ");
}
}
// 转移文件至正式目录
moveToLocalDir(localPath, downloadFileList, config.getTasktype());
}
}