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(),然後讀到創建的路徑下比較好。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章