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