zoukankan      html  css  js  c++  java
  • 通过JAVA对FTP服务器连接,上传,下载,读取,移动文件等

    记录一次对FTP服务器文件内容

    通过Java程序对FTP服务器文件处理:连接,上传,下载,读取,移动文件等。
    需求描述:今天接到一个任务,在Java项目中,读取FTP服务器上的一些文件,进行一些业务操作。处理完之后,将读取过的文件移动到其他目录里面。这就是我需求。

    记录一下使用过程:这里使用的是 org.apache.commons.net.ftp.FTP 这个FTP处理包。

    碰到的几个你可能看这篇文章要解决的碰到的问题,提前说下解决方案:

    1. 完全不知道FTP的API如何使用,无从下手?(直接看方法就行了,很简单)

    2. 访问服务器的时候连接成功,但是使用ListFile()获取不到任何文件?(就是第三个问题描述的)

    3. 想要移动FTP服务器里的文件,如何办?(我使用了Rename操作来完成的。把原有的名字)

    4. 具体业务实现。(你自己厘清自己的实现思路,无论是读取指定文件夹的内容,还是上传或者下载,亦或者是对文件名处理,split拼接,判断指定类型等等。都不是什么难的操作。按照自己的需求,自己去设计实现吧。)

    5. 上传下载读取的话,都是使用流的操作。(看代码吧。)

    6. 聊一下关于修改FTP工作空间的操作和设置数据传输模式。(这个先简单的提供两行代码,可能就已经能够解决你的疑问了)

    //修改工作目录: 就是说,你要处理哪里的文件什么的。看一下Doc就知道了。
    ftpClient.changeWorkingDirectory(pathname); 
    //开启本地传输模式。(还有其他几种模式。Doc文档中有。自行查阅)
    ftpClient.enterLocalPassiveMode();
    

    我这里提炼出来了几个方法,新手使用的话,或者有问题的看代码自行参悟吧。比较简单,这里也主要就是对代码上的记录。(为了保护隐私,隐藏了一些隐私数据和业务处理类。)
    关于代码,先说注意事项:

    1. 用完连接,记得关。
    2. 用完流,记得关。
    3. 有异常,记得处理。

    下面是具体的代码:

    1. 建立FTP连接。
    public FTPClient ftpClient = null;
        //ftp服务器IP
        public String hostname = "XXX10.1001.11";
        //ftp服务器端口号默认为21
        public Integer port = XXX;
        //ftp登录账号
        public String username = "XXX";
        //ftp登录密码
        public String password = "XXX";
    
        public void initFtpClient() {
            ftpClient = new FTPClient();
            ftpClient.setControlEncoding("utf-8");
            try {
                System.out.println("connecting...ftp服务器:"+hostname+":"+port);
                ftpClient.connect(hostname, port); //连接ftp服务器
                ftpClient.login(username, password); //登录ftp服务器
                int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
                if(!FTPReply.isPositiveCompletion(replyCode)){
                    System.out.println("connect failed...ftp服务器:"+hostname+":"+port);
                }
                System.out.println("connect successfu...ftp服务器:"+hostname+":"+port);
            }catch (MalformedURLException e) {
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    调用完 intFTPClient()方法之后,就可以使用ftpClient 来操作FTP服务器了。

    1. 上传.
         /**
         * 上传文件
         * @param pathname ftp服务保存地址
         * @param fileName 上传到ftp的文件名
         *  @param originfilename 待上传文件的名称(绝对地址) *
         * @return*
         **/
    
        public boolean uploadFile( String pathname, String fileName,String originfilename){
            boolean flag = false;
            InputStream inputStream = null;
            try{
                System.out.println("开始上传文件");
                inputStream = new FileInputStream(new File(originfilename));
                initFtpClient();
    
                ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
                CreateDirecroty(pathname);
                ftpClient.makeDirectory(pathname);
                ftpClient.changeWorkingDirectory(pathname);
                ftpClient.enterLocalPassiveMode();
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                flag = true;
                System.out.println("上传文件成功");
            }catch (Exception e) {
                System.out.println("上传文件失败");
                e.printStackTrace();
                return false;
            }finally{
                if(ftpClient.isConnected()){
                    try{
                        ftpClient.disconnect();
                    }catch(IOException e){
                        e.printStackTrace();
                        flag = false;
                    }
                }
                if(null != inputStream){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        flag = false;
                    }
                }
            }
            return flag;
        }
    
    1. 下载
    //我这里在读到文件流的时候,没有保存到本地,直接在程序里面读取转换里面的内容,继续使用了。
    //如果有需要的话,我简单的说下思路。就是 用 ftpClient调用指定文件下的文件,调用 FTPFile[] ftpFileArr = ftpClient.listFiles(path);
    //后续 InputStream in = ftpClient.retrieveFileStream(fileName)。 获取到具体的文件流。然后后续操作 保存流到本地即可。
    
    1. 移动文件(通过Rename完成)
         /**
         *
         * @param nameSet 需要移动的文件目录清单
         * @param fromPath 从哪个目录移动
         * @param toPath 要移动的目录(从根目录开始写。如:/code/yes/:根目录下的code目录下的yes目录
         * @return 返回成功或者失败
         * 注意:目录的话,以/结尾
         */
        public boolean moveFile(List<String> nameSet,String fromPath,String toPath){
    
            //name格式:/code/yesdawaTest1.txt 、/code/yesdawaTest2.txt
            if (nameSet != null && nameSet.size() > 0) {
                for (String s : nameSet) {
                    try {
                        //获取连接:因为一次连接改多个文件只能有一个生效。这里每次修改文件的时候,获取一次新的链接
                        initFtpClient();
                        //改变工作目录
                        ftpClient.changeWorkingDirectory(fromPath);
                        ftpClient.enterLocalPassiveMode();
                        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    
                        String[] split = s.split("/");
                        String name = "";
                        if (split.length > 0) {
                            name = split[split.length - 1];
                        }
                        boolean rename = ftpClient.rename(name, toPath + name);
                        if (rename) {
                            System.out.println(name + "成功移动到:" + toPath + name);
                        }
                        ftpClient.logout();
                    } catch (IOException e) {
                        e.printStackTrace();
                        return false;
                    }
                }
            }
            return true;
        }
    
    1. 对文件名或文件类型的处理和判断。(仅供参考)
         //检查指定/path目录下,是否有.txt结尾的文件。如果有,返回符合要求的.
       /**
        *
        * @param path:要查找的文件目录,如 /code:根目录下的code目录
        * @param ext:要查找的文件类型扩展名,如 .txt
        * @return 返回:符合查找要求的 文件名清单。
        *
        * 返回的 文件名清单:可以先用于处理数据,然后再处理数据成功后,移动这些文件到其他目录下。
        */
       public List<String> checkExistFile(String path, String ext){
    
           //定义一个返回集合:
           List<String> tNameSet = new ArrayList<>();
           //连接服务器
           initFtpClient();
           try {
               //改变工作目录
               ftpClient.changeWorkingDirectory(path);
               ftpClient.enterLocalPassiveMode();
               ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    
               String[] strings = ftpClient.listNames(path);
               if (strings.length > 0) {
                   for (String string : strings) {
                       //如果文件名的长度(带后缀名的)>4 . 才可能是 .txt 结尾的。
                       if (string.length() > ext.length()) {
                           //取得文件后缀名
                           String substring = string.substring(string.length() - ext.length());
                           if (ext.equals(substring)) {
                               System.out.println("目前正在处理文件:" + string);
                               tNameSet.add(string);
                           }
                       }
                   }
               }
               ftpClient.logout();
           } catch (IOException e) {
               System.out.println("读取:"+path+" 目录失败");
               e.printStackTrace();
           }
    
           //返回:符合要求的文件 名字 清单
           return tNameSet;
       }
    
    1. 关闭ftp连接
         /**
         * 关闭FTP服务链接
         * @throws IOException
         */
        public static void disConnection(FTPClient ftpClient){
            try {
                if(ftpClient.isConnected()){
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    OK,以上就是所有问题,有问题可以发邮件联系:16637462812@163.com。 欢迎沟通交流。

  • 相关阅读:
    【大厂面试06期】谈一谈你对Redis持久化的理解?
    【大厂面试05期】说一说你对MySQL中锁的了解?
    【大厂面试04期】讲讲一条MySQL更新语句是怎么执行的?
    【大厂面试03期】MySQL是怎么解决幻读问题的?
    【大厂面试02期】Redis过期key是怎么样清理的?
    【大厂面试01期】高并发场景下,如何保证缓存与数据库一致性?
    透过面试题掌握Redis【持续更新中】
    MySQL慢查询优化(线上案例调优)
    分享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionless+Apollo+SkyWalking的微服务开发框架
    微服务框架Demo.MicroServer运行手册
  • 原文地址:https://www.cnblogs.com/bigbaby/p/13279355.html
Copyright © 2011-2022 走看看