设为首页 收藏本站
查看: 1817|回复: 0

[经验分享] 使用递归方法实现,向FTP服务器上传整个目录结构、从FTP服务器下载整个目录到本地的功能

[复制链接]

尚未签到

发表于 2016-6-10 11:30:19 | 显示全部楼层 |阅读模式
  
我最近由于在做一个关于FTP文件上传和下载的功能时候,发现Apache FTP jar包没有提供对整个目录结构的上传和下载功能,只能非目录类型的文件进行上传和下载操作,后来我查阅很多网上的实现方法,再结合自己的理解、以及符合自己的需求,完成了我自己的apache FTP jar包补充类。

  
上面是背景,基本叙述完毕,下面开始介绍实现方法和代码。

 

一。环境搭建:

1.使用的FileZilla Server开源免费软件,安装过后建立的本地FTP服务器。

2.使用的apache上下载FTP工具包,引用到工程目录中。

3.IDE,Eclipse,JDK6

二。介绍代码。

上传和下载目录的实现原理:对每一个层级的目录进行判断,是为目录类型、还是文件类型。

如果为目录类型,采用递归调用方法,检查到最底层的目录为止结束。

如果为文件类型,则调用上传或者下载方法对文件进行上传或者下载操作。

贴出代码:(其中有些没有代码,可以看看,还是很有用处的)





 

[java] view plaincopyprint?



  • package com.ftp;  
  •   
  • import java.io.File;  
  • import java.io.FileInputStream;  
  • import java.io.FileOutputStream;  
  • import java.io.IOException;  
  • import java.io.InputStream;  
  • import java.io.OutputStream;  
  • import java.net.SocketException;  
  •   
  • import org.apache.commons.net.ftp.FTP;  
  • import org.apache.commons.net.ftp.FTPClient;  
  • import org.apache.commons.net.ftp.FTPClientConfig;  
  • import org.apache.commons.net.ftp.FTPFile;  
  • import org.apache.commons.net.ftp.FTPReply;  
  •   
  • public class RemoteFtpProcess extends FTPClient {  
  •     private static FTPClient ftpClient = new FTPClient();  
  •   
  •     /** 
  •      * 本方法用户登录远程的FTP服务器 
  •      *  
  •      * @param url :表示FTP的IP地址 
  •      * @param port :FTP服务器端口,默认端口为21 
  •      * @param userName :登录FTP的用户名 
  •      * @param password :登录FTP的密码 
  •      *  
  •      * @return FTPClient:返回为FTPClient对象 
  •      */  
  •     public FTPClient loginFtp(String url, int port, String userName,  
  •             String password) {  
  •         try {  
  •             ftpClient.connect(url, port);  
  •             ftpClient.setControlEncoding("UTF-8");  
  •             FTPClientConfig ftpConfig = new FTPClientConfig(FTPClientConfig.SYST_NT);  
  •             ftpConfig.setServerLanguageCode("zh");  
  •             ftpClient.login(userName, password);  
  •             int reply = 0;  
  •             reply = ftpClient.getReplyCode();  
  •             System.out.println(reply);  
  •             if (FTPReply.isPositiveCompletion(reply)) {  
  •                 System.out.println("登录成功!");  
  •             } else {  
  •                 System.out.println("登录失败!");  
  •             }  
  •         } catch (SocketException e) {  
  •             e.printStackTrace();  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •         return ftpClient;  
  •     }  
  •   
  •     /** 
  •      * @param ftpc :退出FTP登录 
  •      * @return boolean :是否已经关闭连接 
  •      *  
  •      * @throws IOException 
  •      */  
  •     public static boolean closeConnections(FTPClient ftpc) throws IOException {  
  •         boolean bool = false;  
  •         ftpc.logout();  
  •         return bool;  
  •     }  
  •   
  •     /** 
  •      * 方法用于上传文件到FTP服务器的指定文件夹中 
  •      *  
  •      * @param fileName :上传文件的名称 
  •      * @param input :上传文件的输入流对象 
  •      * @param toFtpPath :上传到FTP的目的路径 
  •      *  
  •      * @return boolean:表示上传是否成功 
  •      *  
  •      */  
  •     public boolean uploadFileToFtp(String fileName, InputStream input,  
  •             String toFtpPath) {  
  •         boolean bool = false;  
  •         try {  
  •             // 使得能够处理中文编码  
  •             fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");  
  •             toFtpPath = new String(toFtpPath.getBytes("GBK"), "ISO-8859-1");  
  •             // 转到上传文件的FTP目录中  
  •             ftpClient.changeWorkingDirectory(toFtpPath);  
  •             // 设置处理文件的类型为字节流的形式  
  •             ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  
  •             // 如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码  
  •             ftpClient.storeFile(fileName, input);  
  •             input.close();  
  •             bool = true;  
  •         } catch (IOException e) {  
  •             bool = false;  
  •             e.printStackTrace();  
  •         }   
  •         return bool;  
  •     }  
  •   
  •     /** 
  •      * 方法用于从FTP服务器中下载文件 
  •      *  
  •      * @param ftpUrl :下载文件所处FTP中路径 
  •      * @param fileName :下载的文件名称 
  •      * @param outputSream :下载文件的输出流对象 
  •      *  
  •      * @return boolean :表示是否上传成功 
  •      *  
  •      */  
  •     public boolean downloadFileFromFtp(String ftpUrl, String fileName,  
  •             OutputStream outputStream) {  
  •         boolean bool = false;  
  •         try {  
  •             ftpClient.changeWorkingDirectory(ftpUrl);  
  •             FTPFile[] ftpFile = ftpClient.listFiles();  
  •             for (int i = 0; i < ftpFile.length; i++) {  
  •                 if (fileName.equals(ftpFile.getName())) {  
  •                     ftpClient.retrieveFile(new String(ftpFile.getName()  
  •                             .getBytes("GBK"), "ISO-8859-1"), outputStream);  
  •                     outputStream.flush();  
  •                     outputStream.close();  
  •                 }  
  •             }  
  •             bool = true;  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •             bool = false;  
  •         }  
  •         return bool;  
  •     }  
  •   
  •     /** 
  •      * 方法用户删除FTP上的指定的文件 
  •      *  
  •      * @param fileUrl :文件在FTP中的路径 
  •      * @param fileName :文件的名称 
  •      *  
  •      * @return boolean:删除是否成功 
  •      */  
  •     public boolean deleteFileOnFtp(String fileUrl, String fileName) {  
  •         boolean bool = false;  
  •         try {  
  •             ftpClient.changeWorkingDirectory(fileUrl);  
  •             FTPFile[] ftpFiles = ftpClient.listFiles();  
  •             System.out.println(ftpFiles.length);  
  •             for (int i = 0; i < ftpFiles.length; i++) {  
  •                 if (fileName.equals(ftpFiles.getName())) {  
  •                     ftpClient.deleteFile(fileName);  
  •                 }  
  •             }  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •         return bool;  
  •     }  
  •   
  •     /** 
  •      * 判断指定文件中是否存在相同名称的文件 
  •      *  
  •      * @param remotePath :FTP上的远程目录 
  •      * @param fileName:文件名称 
  •      * @return boolean :判断是否存在相同名称 
  •      *  
  •      */  
  •     public boolean isSameName(String remotePath, String fileName) {  
  •         boolean bool = false;  
  •         try {  
  •             FTPFile[] ftpFiles = ftpClient.listFiles();  
  •             System.out.println(ftpFiles.length);  
  •             ftpClient.changeWorkingDirectory(remotePath);  
  •             for (int i = 0; i < ftpFiles.length; i++) {  
  •                 if (fileName.equals(ftpFiles.getName())) {  
  •                     System.out.println("存在和指定文件相同名称的文件");  
  •                     bool = true;  
  •                 } else {  
  •                     bool = false;  
  •                 }  
  •             }  
  •         } catch (Exception e) {  
  •             bool = false;  
  •         }  
  •         return bool;  
  •     }  
  •   
  •     /** 
  •      * 更改文件名称 
  •      *  
  •      */  
  •     public String changeName(String remotePath, String fileName, String newName) {  
  •         if (isSameName(remotePath, fileName)) {  
  •             fileName = fileName + "." + newName;  
  •         }  
  •         return fileName;  
  •     }  
  •       
  •       
  •     public static void newFileOnFTP(String pathName){  
  •         try {  
  •             ftpClient.mkd(pathName);  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •     }  
  •       
  •     //上传整个目录到FTP的指定目录中  
  •     public void uploadDirFiles(String dirPath,String toRemotePath) throws IOException{  
  •         if (dirPath!=null && !dirPath.equals("")) {  
  •             //建立上传目录的File对象  
  •             File dirFile = new File(dirPath);  
  •             //判断File对象是否为目录类型  
  •             if (dirFile.isDirectory()) {  
  •                 //如果是目录类型。  
  •                 //在FTP上创建一个和File对象文件相同名称的文件夹  
  •                 ftpClient.makeDirectory(toRemotePath+"//"+dirFile.getName());  
  •                 //获得File对象中包含的子目录数组  
  •                 File[] subFiles = dirFile.listFiles();  
  •                 //路径  
  •                 String path = toRemotePath+"//"+dirFile.getName();  
  •                 System.out.println(path);  
  •                 //判断数组是否为空  
  •                 if (subFiles!=null && subFiles.length>0) {  
  •                     //遍历整个File数组  
  •                     for (int i = 0; i < subFiles.length; i++) {  
  •                         //判断是否为目录类型  
  •                         if (subFiles.isDirectory()) {  
  •                             //如果为目录类型  
  •                             //跳转到FTP的根目录层级  
  •                             ftpClient.changeWorkingDirectory("//");  
  •                             //在FTP上建立相同的目录名称  
  •                             ftpClient.makeDirectory(path+"//"+subFiles.getName());  
  •                             //递归调用自身方法,进行到下一层级的目录循环  
  •                             uploadDirFiles(subFiles.getAbsolutePath(), path);  
  •                         } else {  
  •                             //如果为文件类型  
  •                             //建立一个文件输出流对象  
  •                             FileInputStream input = new FileInputStream(subFiles);  
  •                             //调用文件上传方法,将文件上传到FTP上  
  •                             uploadFileToFtp(subFiles.getName(), input, path+"//");  
  •                             //关闭文件输入流  
  •                             input.close();  
  •                         }  
  •                     }  
  •                 }  
  •             } else {  
  •                 //如果为文件类型  
  •                 //建立一个文件输出流对象  
  •                 FileInputStream input = new FileInputStream(dirFile);  
  •                 //调用文件上传方法,将文件上传到FTP上  
  •                 uploadFileToFtp(dirFile.getName(), input, toRemotePath);  
  •                 //关闭文件输入流  
  •                 input.close();  
  •             }  
  •         }  
  •     }  
  •       
  •     //本方法用于下载FTP上的目录结构到本地中  
  •     public void downloadDirFiles(String remotePath,String localPath,String fileName) throws IOException{  
  •         if (remotePath!=null && !remotePath.equals("")) {  
  •             //在本地建立一个相同的文件目录  
  •             File localFile = new File(localPath+"\\"+fileName);  
  •             localFile.mkdirs();  
  •             //获得目录在本地的绝对路径  
  •             localPath = localFile.getAbsolutePath();  
  •             System.out.println(localPath);  
  •             //获得FTPFile对象数组  
  •             FTPFile[] ftpFiles = ftpClient.listFiles(new String(remotePath.getBytes("GBK"),"ISO-8859-1"));  
  •             if (ftpFiles!=null && ftpFiles.length>0) {  
  •                 for (int i = 0; i < ftpFiles.length; i++) {  
  •                     FTPFile subFile = ftpFiles;  
  •                     //判断是否为目录结构  
  •                     if (subFile.isDirectory()) {  
  •                         //如果为目录结构  
  •                         //调用自身方法,进行下一层级目录循环  
  •                         downloadDirFiles(remotePath+"//"+subFile.getName(), localPath, subFile.getName());  
  •                     } else {  
  •                         //如果不为目录结构,为文件类型  
  •                         FileOutputStream outputStream = new FileOutputStream(new File(localPath+"\\"+subFile.getName()));  
  •                         //调用下载方法对文件进行下载  
  •                         downloadFileFromFtp(remotePath, subFile.getName(), outputStream);  
  •                         //关闭文件输出流  
  •                         outputStream.close();  
  •                     }  
  •                 }  
  •             }  
  •         }  
  •     }  
  • }  



 



编写一个测试main类,进行测试。
 

 

[java] view plaincopyprint?



  • package com.ftp;  
  •   
  • import java.io.IOException;  
  •   
  • import org.apache.commons.net.ftp.FTPClient;  
  •   
  • public class TestMain {  
  •     public static void upload(){  
  •         RemoteFtpProcess remote = new RemoteFtpProcess();  
  •         FTPClient ftpClient = remote.loginFtp("127.0.0.1"21"root""root");  
  •         try {  
  •             remote.uploadDirFiles("D:\\FTPTestA""//");  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •     }  
  •       
  •     public static void download(){  
  •         RemoteFtpProcess remote = new RemoteFtpProcess();  
  •         FTPClient ftpClient = remote.loginFtp("127.0.0.1"21"root""root");  
  •         try {  
  •             remote.downloadDirFiles("\\FTPTest""E://", "FTPTestB  
  • ");  
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •     }  
  •       
  •     public static void main(String[] args) {  
  •         download();  
  •     }  
  • }  

  文章转自:http://blog.csdn.net/captaingan/article/details/6970332

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-228605-1-1.html 上篇帖子: 利用ftpclient下载文件,解决用window.open打开ftp地址中有中文,不能下载的问题(原创) 下篇帖子: [技术分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表