package utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class FtpUtil
{
/**
* 連接ftp服務器 獲取連接對象
* 功能詳細描述
* @param host
* @param port
* @param userName
* @param password
* @return
* @remark create wwx716383 2019年7月18日 需求編號_需求名稱
*/
public static FTPClient getFtpClient(String host,int port,String userName,String password,String character){
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding(character);
try {
System.out.println("connecting...ftp服務器:" + host + ":" + port);
ftpClient.connect(host, port); //連接ftp服務器
ftpClient.login(userName, password); //登錄ftp服務器
int replyCode = ftpClient.getReplyCode(); //是否成功登錄服務器
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.println("connect failed...ftp服務器:" + host + ":" + port);
return null;
}else{
System.out.println("connect successful...ftp服務器:" + host + ":" + port);
//避免忘了開啓被動模式
ftpClient.enterLocalPassiveMode();
return ftpClient;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 下載文件 下載的文件名同
* 功能詳細描述
* @param ftpClient
* @param filePath ftp端目錄
* @param fileName ftp端文件名
* @param loalPath 本地下載目錄 不包括文件名
* @param loalPath 本地下載目錄 不包括文件名
* @return disconnectAfterDownload 下載完是否關閉ftp連接
* @throws IOException
* @remark create wwx716383 2019年7月18日 需求編號_需求名稱
*/
/*
* 項目中使用commons-net-3.0.1.jar實現FTP文件的下載,在windows xp上運行正常,但是放到linux上,卻出現問題,
* 程序運行到 FTPClient.listFiles()或者FTPClient.retrieveFile()方法時,就停止在那裏,什麼反應都沒有,出現假死狀態。
* google一把,發現很多人也出現了此類問題,最終在一個帖子裏找到了解決辦法。在調用這兩個方法之前,調用FTPClient.enterLocalPassiveMode();
* 這個方法的意思就是每次數據連接之前,ftp client告訴ftp server開通一個端口來傳輸數據。爲什麼要這樣做呢,因爲ftp server可能每次開啓不同的端口來傳輸數據,
* 但是在linux上,由於安全限制,可能某些端口沒有開啓,所以就出現阻塞。OK,問題解決。
*/
public static Map<String, String> downloadFile(FTPClient ftpClient,String filePath,String fileName,String loalPath,boolean disconnectAfterDownload){
Map<String, String> resultMap=new HashMap<>();
resultMap.put("resultCode", "-1");
FileOutputStream os=null;
try
{
/*
* 1 在FTP服務中,涉及到客戶端和服務器端的連接,連接就會涉及到端口的打開問題;
* 2 而端口的打開中,又涉及到主動模式和被動模式。主動模式:客戶端開放端口給服務端用;被動模式:服務端開放端口給客戶端用。由於很多客戶端在防火牆內,
* 開放端口給服務器端用比較困難。所以用被動模式的時候比較多。
* 3 如果涉及到了內網、局域網等環境時,出現FTP連接問題,也可以考慮是否是因爲連接模式引起的。
*/
ftpClient.enterLocalPassiveMode();
//切換到文件所在目錄
ftpClient.changeWorkingDirectory(filePath);
//獲取目錄下的文件對象
FTPFile[] ftpFiles=ftpClient.listFiles(filePath);
//判斷該目錄下是否有文件
if(ftpFiles.length>0){
for(FTPFile file : ftpFiles){
if(fileName.equalsIgnoreCase(file.getName())){
File localFile = new File(loalPath + "/" + file.getName());
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
System.out.println(file.getName());
resultMap.put("resultCode", "200");
resultMap.put("message", "下載成功!");
resultMap.put("downloadPath", loalPath + "/" + file.getName());
System.out.println("下載成功!");
break;
}
}
if(resultMap.get("resultCode").equals("-1")){
resultMap.put("message", "ftp目錄下未找到該文件,目錄:"+filePath+" ,文件:"+fileName);
}
}else{
resultMap.put("message", "ftp目錄下文件數爲0,目錄:"+filePath);
}
}
catch(IOException e)
{
e.printStackTrace();
resultMap.put("message", "下載異常!"+e.getMessage());
System.out.println("下載異常!"+e.getMessage());
}
finally
{
if(ftpClient.isConnected()&&disconnectAfterDownload){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != os){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return resultMap;
}
}