zoukankan      html  css  js  c++  java
  • 使用递归方法实现,向FTP服务器上传整个目录结构、从FTP服务器下载整个目录到本地的功能

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

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

    一。环境搭建:

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

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

    3.IDE,Eclipse,JDK6

    二。介绍代码。

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

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

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

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

    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[i].getName())) {  
                        ftpClient.retrieveFile(new String(ftpFile[i].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[i].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[i].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[i].isDirectory()) {  
                                //如果为目录类型  
                                //跳转到FTP的根目录层级  
                                ftpClient.changeWorkingDirectory("//");  
                                //在FTP上建立相同的目录名称  
                                ftpClient.makeDirectory(path+"//"+subFiles[i].getName());  
                                //递归调用自身方法,进行到下一层级的目录循环  
                                uploadDirFiles(subFiles[i].getAbsolutePath(), path);  
                            } else {  
                                //如果为文件类型  
                                //建立一个文件输出流对象  
                                FileInputStream input = new FileInputStream(subFiles[i]);  
                                //调用文件上传方法,将文件上传到FTP上  
                                uploadFileToFtp(subFiles[i].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[i];  
                        //判断是否为目录结构  
                        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类,进行测试。

    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

  • 相关阅读:
    2021.1.28 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2020.12.14 个人训练赛补题报告
    2020.11.28 2020团体程序设计天梯赛补题报告
    2020.12.3 Codeforces Beta Round #73(Div2)补题报告
    Xhorse VVDI Prog V5.0.6 is Ready for BCM2 Adapter
    Program 2021 Ford Bronco All Keys Lost using VVDI Key Tool Plus
    Xhorse VVDI Prog V5.0.4 Software Update in July 2021
    How to use Xhorse VVDI2 to Exchange BMW FEM/BDC Module?
  • 原文地址:https://www.cnblogs.com/dreammyle/p/4256997.html
Copyright © 2011-2022 走看看