解决的两个问题
1.设置连接超时时间,如下:
ftp.setConnectTimeout(3*1000);//设置连接ftp超时时间3秒
2.文件下载后,出现文件中中文乱码的情况,解决办法是,设置编码格式,如下:
ftp.setFileType(FTP.BINARY_FILE_TYPE);//定义编码格式 防止文件中的中文出现乱码
以下列出测试可用的源码:
LoadConfigs
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class LoadConfigs {
/**
* 系统的配置文件类路径
*/
public static final String CONFIG_PATH = "/conf/config.properties";
private static Properties configs=new Properties();;
private static String propertiesPath = ResourceUtil.getAbsolutePath(CONFIG_PATH);
private static void initConfigs(){
try {
Reader inStream = new InputStreamReader(new FileInputStream(propertiesPath), "UTF-8");
configs.load(inStream);
}catch (IOException e){
System.err.println("load config.properties error");
}
}
public static Map getConfig(){
initConfigs();
Map<String,String> configMap = new HashMap<String, String>();
configMap.put("ftpServer.backup.host.ip",configs.getProperty("ftpServer.backup.host.ip"));
configMap.put("ftpServer.backup.host.port",configs.getProperty("ftpServer.backup.host.port"));
configMap.put("ftpServer.backup.host.account",configs.getProperty("ftpServer.backup.host.account"));
configMap.put("ftpServer.backup.host.pwd",configs.getProperty("ftpServer.backup.host.pwd"));
configMap.put("ftpServer.backup.host.path",configs.getProperty("ftpServer.backup.host.path"));
configMap.put("linuxOS.backup.local.path",configs.getProperty("linuxOS.backup.local.path"));
configMap.put("winOS.backup.local.path",configs.getProperty("winOS.backup.local.path"));
return configMap;
}
public static String getConfig(String key){
return configs.getProperty(key);
}
public enum OS {
WIN, LINUX, OTHER
}
public static OS checkOSType() {
String osName = System.getProperty("os.name");
if (osName.toLowerCase().startsWith("win")) {
return OS.WIN;
} else if (osName.toLowerCase().startsWith("lin")) {
return OS.LINUX;
} else {
return OS.OTHER;
}
}
}
ResourceUtil
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
public class ResourceUtil {
/**
* 工程内资源到文件系统的拷贝。
* 从类路径到文件系统路径
*
* @param resourceAbsoluteClassPath 绝对类路径
* @param targetFile 目标文件
* @throws java.io.IOException
*/
public static void copyResourceToFile(String resourceAbsoluteClassPath,
File targetFile) throws IOException {
InputStream is = ResourceUtil.class.getResourceAsStream(resourceAbsoluteClassPath);
if (is == null) {
throw new IOException("Resource not found! " + resourceAbsoluteClassPath);
}
OutputStream os = null;
try {
os = new FileOutputStream(targetFile);
byte[] buffer = new byte[2048];
int length;
while ((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
os.flush();
} finally {
try {
is.close();
if (os != null) {
os.close();
}
} catch (Exception ignore) {
// ignore
}
}
}
public static String getAbsolutePath(String classPath) {
URL configUrl = ResourceUtil.class.getResource(classPath);
if (configUrl == null) {
return null;
}
try {
return configUrl.toURI().getPath();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
config.properties
#ftp日志备份相关配置
ftpServer.backup.host.ip=192.168.20.170
ftpServer.backup.host.port=21
ftpServer.backup.host.account=kkk
ftpServer.backup.host.pwd=kkkkkk
ftpServer.backup.host.path=/backup/log/
linuxOS.backup.local.path=/usr/local/backup/log/
winOS.backup.local.path=e:\\
FTPTool
import java.io.*;
import java.util.Map;
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.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import wst.phone.util.LoadConfigs;
public class FtpTool {
private static LoadConfigs.OS osType = LoadConfigs.checkOSType();
// //ftp常量
private static Map configMap = LoadConfigs.getConfig();
private static String FTP_BACKUP_HOST_IP = (String) configMap.get("ftpServer.backup.host.ip");
private static String FTP_BACKUP_HOST_PORT = (String) configMap.get("ftpServer.backup.host.port");
private static String FTP_BACKUP_HOST_ACCOUNT = (String) configMap.get("ftpServer.backup.host.account");
private static String FTP_BACKUP_HOST_PWD = (String) configMap.get("ftpServer.backup.host.pwd");
private static String FTP_BACKUP_HOST_PATH = (String) configMap.get("ftpServer.backup.host.path");
private static String LINUX_BACKUP_LOCAL_PATH = (String) configMap.get("linuxOS.backup.local.path");
private static String WIN_BACKUP_LOCAL_PATH = (String) configMap.get("winOS.backup.local.path");
private static String BACKUP_LOCAL_PATH = (osType == LoadConfigs.OS.LINUX ? LINUX_BACKUP_LOCAL_PATH : WIN_BACKUP_LOCAL_PATH);
/**
* 获得连接-FTP方式
*
* @param hostIp FTP服务器地址
* @param port FTP服务器端口
* @param userName FTP登录用户名
* @param passWord FTP登录密码
* @return FTPClient
*/
public FTPClient getConnectionFTP(String hostIp, int port, String userName, String passWord) throws Exception{
//创建FTPClient对象
FTPClient ftp = new FTPClient();
ftp.setConnectTimeout(3*1000);//设置连接ftp超时时间3秒
try {
//连接FTP服务器
ftp.connect(hostIp, port);
//下面三行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件
ftp.setControlEncoding("UTF-8");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
//登录ftp
ftp.login(userName, passWord);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
ftp.disconnect();
System.out.println("Connect FTP Server failed.");
}
System.out.println("Connect FTP Server success.");
} catch (Exception e){
e.printStackTrace();
throw e;
}
return ftp;
}
/**
* FTP参数固定方式,参数在配置文件中
*
* @return FTPClient
*/
public FTPClient getConnectionFTP() throws Exception{
return getConnectionFTP(FTP_BACKUP_HOST_IP, Integer.valueOf(FTP_BACKUP_HOST_PORT),
FTP_BACKUP_HOST_ACCOUNT, FTP_BACKUP_HOST_PWD);
}
/**
* 关闭连接-FTP方式
*
* @param ftp FTPClient对象
* @return boolean
*/
public boolean closeFTP(FTPClient ftp){
if (ftp.isConnected()) {
try {
ftp.disconnect();
System.out.println("Ftp connection closed.");
return true;
} catch (Exception e){
e.printStackTrace();
}
}
return false;
}
/**
* 上传文件-FTP方式
*
* @param ftp FTPClient对象
* @param ftpPath FTP服务器上传路径
* @param localFileIncludePath 本地文件全路径
* @param inputStream 输入流
* @return boolean
*/
public boolean uploadFile(FTPClient ftp, String ftpPath, String localFileIncludePath, InputStream inputStream) throws Exception{
boolean success = false;
try {
ftp.changeWorkingDirectory(ftpPath);//转移到指定FTP服务器目录
FTPFile[] fs = ftp.listFiles();//得到目录的相应文件列表
localFileIncludePath = FtpTool.changeName(localFileIncludePath, fs);
localFileIncludePath = new String(localFileIncludePath.getBytes("UTF-8"), "UTF-8");
ftpPath = new String(ftpPath.getBytes("UTF-8"), "UTF-8");
//转到指定上传目录
ftp.changeWorkingDirectory(ftpPath);
//将上传文件存储到指定目录
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码
ftp.storeFile(localFileIncludePath, inputStream);
//关闭输入流
inputStream.close();
//退出ftp
ftp.logout();
//表示上传成功
success = true;
System.out.println("Upload success.");
} catch (Exception e){
e.printStackTrace();
throw e;
}
return success;
}
/**
* 上传文件到FTP服务器的固定路径,路径见配置文件
*
* @param ftp
* @param fileName
* @param inputStream
* @return
*/
public boolean uploadFile(FTPClient ftp, String fileName, InputStream inputStream) throws Exception{
return uploadFile(ftp, FTP_BACKUP_HOST_PATH, BACKUP_LOCAL_PATH + fileName, inputStream);
}
/**
* 删除文件-FTP方式
*
* @param ftp FTPClient对象
* @param ftpPath FTP服务器上传地址
* @param ftpFileName FTP服务器上要删除的文件名
* @return
*/
public boolean deleteFile(FTPClient ftp, String ftpPath, String ftpFileName) throws Exception{
boolean success = false;
try {
ftp.changeWorkingDirectory(ftpPath);//转移到指定FTP服务器目录
ftpFileName = new String(ftpFileName.getBytes("UTF-8"), "UTF-8");
ftpPath = new String(ftpPath.getBytes("UTF-8"), "UTF-8");
ftp.deleteFile(ftpFileName);
ftp.logout();
success = true;
} catch (Exception e){
e.printStackTrace();
throw e;
}
return success;
}
/**
* 从ftp删除文件
* @param ftp
* @param ftpFileName
* @return
*/
public boolean deleteFile(FTPClient ftp, String ftpFileName) throws Exception{
return deleteFile(ftp, FTP_BACKUP_HOST_PATH, ftpFileName);
}
/**
* 下载文件-FTP方式
*
* @param ftp FTPClient对象
* @param ftpPath FTP服务器路径
* @param ftpFileName FTP服务器文件名
* @param localSavePath 本里存储路径
* @return boolean
*/
public boolean downFile(FTPClient ftp, String ftpPath, String ftpFileName, String localSavePath) throws Exception{
boolean success = false;
try {
ftp.changeWorkingDirectory(ftpPath);//转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles(); //得到目录的相应文件列表
for (FTPFile ff : fs) {
if (ff.getName().equals(ftpFileName)) {
// File localFile = new File(localSavePath + "\\" + ff.getName());
File localFile = new File(localSavePath + ff.getName());
OutputStream outputStream = new FileOutputStream(localFile);
//将文件保存到输出流outputStream中
ftp.setFileType(FTP.BINARY_FILE_TYPE);//定义编码格式 防止文件中的中文出现乱码
ftp.retrieveFile(new String(ff.getName().getBytes("UTF-8"), "UTF-8"), outputStream);
outputStream.flush();
outputStream.close();
System.out.println("Download success.");
}
}
ftp.logout();
success = true;
} catch (Exception e){
e.printStackTrace();
throw e;
}
return success;
}
/**
* 从ftp下载文件,固定参数见配置文件
*
* @param ftp
* @param ftpFileName
* @return
*/
public boolean downFile(FTPClient ftp, String ftpFileName) throws Exception{
return downFile(ftp, FTP_BACKUP_HOST_PATH, ftpFileName, BACKUP_LOCAL_PATH);
}
/**
* 判断是否有重名文件
*
* @param fileName
* @param fs
* @return
*/
public static boolean isFileExist(String fileName, FTPFile[] fs) {
for (int i = 0; i < fs.length; i++) {
FTPFile ff = fs[i];
if (ff.getName().equals(fileName)) {
return true; //如果存在返回 正确信号
}
}
return false; //如果不存在返回错误信号
}
/**
* 根据重名判断的结果 生成新的文件的名称
*
* @param fileName
* @param fs
* @return
*/
public static String changeName(String fileName, FTPFile[] fs) {
int n = 0;
// fileName = fileName.append(fileName);
while (isFileExist(fileName.toString(), fs)) {
n++;
String a = "[" + n + "]";
int b = fileName.lastIndexOf(".");//最后一出现小数点的位置
int c = fileName.lastIndexOf("[");//最后一次"["出现的位置
if (c < 0) {
c = b;
}
StringBuffer name = new StringBuffer(fileName.substring(0, c));//文件的名字
StringBuffer suffix = new StringBuffer(fileName.substring(b + 1));//后缀的名称
fileName = name.append(a) + "." + suffix;
}
return fileName.toString();
}
}