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(),然后读到创建的路径下比较好。



猜你喜欢

转载自blog.csdn.net/u010454729/article/details/78258700
今日推荐