JAVA FTPClient——遠端檔案操作
Preface:最近忙的一個query理解服務的專案,關於分詞工具的問題,升級為使用北京側的分詞工具,屬於工程性質的。其中,需要載入動態庫和model資料夾,而且,由於服務部署到多臺機器上,為此,動態庫和model資料夾不能直接放到程式碼上帶過去,而是放到FTP機器上,當服務部署到多個機器或者機器擴容的時候,避免手工操作檔案,而是在服務啟動的時候,通過java FTPClient自動把檔案拉到服務所在的機器,然後在程式碼裡面載入動態庫和Model,拿到分詞控制代碼。每來了一個請求,通過該分詞控制代碼對這個請求裡面的query進行分詞。
一、FTPClient所需包
基本上使用apache的jar包,在程式碼中import即可
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;import org.apache.commons.net.ftp.FTPReply;
說明:
FTPClient:用於連線機器
FTPFile:用於解析FTP機器上資料夾中的檔案
FTPReply:用於判斷是否連線成功
二、FTP連線
邏輯流程:FTPClient ftpClient = new FTPClient(); try { //連線FTP ftpClient.connect(ftpHost, ftpPort); } catch (SocketException e) { e.printStackTrace(); LOGGER.info("FTP的IP地址可能錯誤,請正確配置。"); } catch (IOException e) { e.printStackTrace(); LOGGER.info("hose port可能有問題"); } try { ftpClient.login(username, password); } catch (IOException e) { e.printStackTrace(); LOGGER.info("FTP賬號密碼可能有問題"); } if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { LOGGER.info("未連線到FTP,使用者名稱或密碼錯誤"); } else { LOGGER.info("FTP連線成功"); }
是否需要連線FTP:判斷動態庫和model資料夾在機器上,則需要連線FTP
連線FTP:主機名、埠號、賬號、密碼(滷煮用FTP機器的ip代替主機名,使用了主機名反而不行)
是否連線成功:FTPReply
注意:埠號為FTP埠號,非機器埠號(可能不同,多試下)
三、FTPClient傳輸
程式碼
try{ ftpClient.changeWorkingDirectory(remotePath); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//傳輸的時候以二進位制傳輸,一定要加這行,不然(檔案變小)天大的坑!!! FTPFile[] fs = ftpClient.listFiles(); for(FTPFile ff : fs){ File localFile = new File(localPath + ff.getName()); if(ff.isDirectory()){ //將路徑改到子資料夾,對子資料夾進行下載 ftpClient.changeWorkingDirectory(remotePath+ff.getName()); FTPFile[] fsubs = ftpClient.listFiles(); for(FTPFile fsubf : fsubs){ //建立子資料夾 File localSublDir = new File(localPath + ff.getName()); if(!localSublDir.exists()){ localSublDir.mkdir(); } //獲取子資料夾裡面的子檔案的名字 File localSubFile = new File(localPath + ff.getName() +"/"+ fsubf.getName()); OutputStream is = new FileOutputStream(localSubFile); ftpClient.retrieveFile(fsubf.getName(), is); is.close(); } ftpClient.changeWorkingDirectory(remotePath); }else{ OutputStream is = new FileOutputStream(localFile); ftpClient.retrieveFile(ff.getName(), is); is.close(); } } } catch (IOException e) { e.printStackTrace(); }
說明
changeWorkingDirectory():定位到FTP機器上資料夾的位置
setFileType():設定FTP傳輸型別。最好使用二進位制傳輸,另外還有傳輸編碼格式(utf-8)設定等,不設定的話,傳輸後的檔案可能有所變化,使用不了了,天大的坑!!!
listFiles():將資料夾裡面的檔案遍歷出來
localFile:本地File名
is:將File轉為檔案流
retrieveFile():將這個檔案寫到這個檔案流中
注:
由於滷煮的資料夾裡還有資料夾,兩層,為此,需要進入子資料夾進行傳輸,不然的話,子資料夾裡的檔案傳輸不過去;當資料夾多層的時候,需要遞迴傳輸。
有的時候,可能涉及許可權問題。從FTP機器上的某個路徑傳到另外一個機器只讀的路徑下,setReadable、setWritable倆函式似乎根本沒用。咋整的話,只能mkdir(),然後讀到建立的路徑下比較好。