FTPClient的使用(二) ftp(文件夹和文件)下载,上传,复制备份

原创文章,转载请注明出处

下例亮色部分分别是下载,复制备份,上传的方法,其他多余的代码为路径处理,可根据自己的情况处理:

如何登陆退出FTP请看上一篇,

    类开始的全局变量    

    private static FTPClient ftpClient = new FTPClient();
    private String fileUrl = "";
    boolean flag = true;


private void auditPass4StaticPage(PageFile pageFile, Integer versioin) throws Exception {

        String longPath = pageFile.getPath();//获取path和state_path
        String lpath = longPath.substring(0, longPath.lastIndexOf("/"));
        String path = lpath.substring(0, lpath.lastIndexOf("/"));//获得需要下载的压缩包所在的文件夹地址

        Map<String, Object> domainMap = new HashMap<String, Object>();

        String baselocalPath = System.getProperty("catalina.home");//"C:";\\\\Tomcat 8.0
        String subPath = path.substring(path.lastIndexOf("/") + 1, path.length());
        String fileName = subPath + ".zip";
        String remotePath = path.substring(path.indexOf(".cn/") + 3);
        if (remotePath != null && !remotePath.equals("")) {
            //链接本地ftp
            this.loginFtp(domainMap);
            File localFile = new File(baselocalPath + remotePath);//在本地建立一个相同的文件目录
            localFile.mkdirs();
            String localPath = localFile.getAbsolutePath();//获得目录在本地的绝对路径
            System.out.println(localPath);
            FileOutputStream outputStream = new FileOutputStream(new File(localPath + "/" + fileName));//输出流

            //调用下载方法下载文件到本地三个参数示例

            //  1:  /StaticPage/20170914/1505373329228    2:   /StaticPage/20170914/1505373329228     3:   java.io.FileOutputStream@59be2620

            boolean dsuccess = this.downloadFileFromFtp(remotePath, fileName, outputStream);
            if (dsuccess) {//如果下载成功则解压上传
                UnCompressFile.unZipFiles(localPath + "/" + fileName, localPath + "/" + subPath + "/");//解压
                //退出本地的FTP
                boolean close = AuditPageServiceImpl.closeConnections(ftpClient);
                //获取远程FTP链接
                String statePath = pageFile.getStaticPath();
                String domainName = statePath.substring(0, statePath.indexOf("/"));//域名
                domainMap.put("domainName", domainName);
                Domain domain = auditPageDao.getDomainByName(domainName);
                String userName = domain.getFtpAccount();
                String pw = domain.getFtpPassword();
                domainMap.put("userName", userName);
                domainMap.put("pw", pw);
                String toRemotePath = statePath.substring(statePath.indexOf("/"));
                String dirPath = localPath + "/" + subPath;//解压后的文件夹路径
                if (close) {
                    //链接远程FTP
                    this.loginFtp(domainMap);
                    //插码
                    String indexLocal = (dirPath + "/" + "index.html").replaceAll("\\\\", "/");
                    ResReviewHtmlDTO review = HtmlContentReviewUtil.reviewHtmlFile(indexLocal, true);
                    if (review.getMessage() != null) {
                        logger.error("解压后插码发生错误:" + review.getMessage());
                        throw new BusinessException("解压后插码发生错误,message=" + review.getMessage());
                    }
                    //XXX3.5、备份FTP历史数据进版本文件夹 :备份css、js、images、以及index.html或其他历史.html页
                    String hVersion = "V" + String.valueOf(versioin - 1);
                    String urlSuffix = pageFile.getUrlSuffix();
                    if (versioin != 1) {
                        String dirPathCss = toRemotePath + "/css";
                        String dirPathJs = toRemotePath + "/js";
                        String dirPathImages = toRemotePath + "/images";
                        String dirPathPage = toRemotePath + "/" + urlSuffix;


                        String toRemotePathCss = toRemotePath + "/" + hVersion + "/css";
                        String toRemotePathJs = toRemotePath + "/" + hVersion + "/js";
                        String toRemotePathImages = toRemotePath + "/" + hVersion + "/images";
                        String toRemotePathPage = toRemotePath + "/" + hVersion;
                        //参数示例:/chenyaoyu/SH/pc/diMJ5q/css      /chenyaoyu/SH/pc/diMJ5q/V2/css    备份的文件夹以及他下边的文件
                        boolean cssSuccess = this.copyDirectiory(dirPathCss, toRemotePathCss, null);//备份css文件夹
                        boolean jsSuccess = this.copyDirectiory(dirPathJs, toRemotePathJs, null);//备份js文件夹

                        boolean imagesSuccess = this.copyDirectiory(dirPathImages, toRemotePathImages, null);//备份images文件夹

 //同一个方法此处直接备份文件,参数示例:要备份文件/chenyaoyu/SH/pc/diMJ5q/index.html   备份到路径  /chenyaoyu/SH/pc/diMJ5q/V2   备份文件的别名 : index.html

                        boolean indexSuccess = this.copyDirectiory(dirPathPage, toRemotePathPage, urlSuffix);//备份index.html或其他历史页面
                        if (!cssSuccess || !jsSuccess || !imagesSuccess || !indexSuccess) {
                            logger.error("备份正式FTP环境文件出错");
                            throw new BusinessException("备份正式FTP环境文件出错");
                        }
                    }
                    //上传

                    String afterDirPath = dirPath.replaceAll("\\\\", "/");

//要上传的地址:/chenyaoyu/SH/pc/diMJ5q   文件所在地址 C:/Tomcat 8.0/StaticPage/20170914/1505373329228/1505373329228   别名问题普通世通可忽略此参数 index.html

                    boolean upSuccess = this.uploadDirFiles(toRemotePath, afterDirPath, urlSuffix);
                    if (!upSuccess) {
                        logger.error("上传文件到正式FTP时出错");
                        throw new BusinessException("上传文件到正式FTP时出错");
                    }
                } else {
                    logger.debug("*******本地FTP关闭链接失败");
                    throw new BusinessException("本地FTP关闭链接失败");
                }
            } else {
                logger.debug("*******从本地服务器下载出错");
                throw new BusinessException("从本地服务器下载文件出错出错");
            }
        }

    }

/**
     * 方法用于从FTP服务器中下载文件
     * @param ftpUrl       :下载文件所处FTP中路径
     * @param fileName     :下载的文件名称
     * @param outputStream :下载文件的输出流对象
     * @return boolean :表示是否上传成功
     */
    public boolean downloadFileFromFtp(String ftpUrl, String fileName,OutputStream outputStream) {
        boolean bool = false;
        try {
            ftpClient.enterLocalPassiveMode();//避免:java.net.SocketTimeoutException: Read timed out
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//二进制方式读取
            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;
    }

    /**
     * 复制文件夹.
     *
     * @param sourceDir
     * @param targetDir
     * @throws IOException
     */
    public boolean copyDirectiory(String sourceDir, String targetDir, String keyUrlSuffix) throws IOException {
        // 新建目标目录  
        int reply = 0;
        reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
        } else {
            if (!ftpClient.changeWorkingDirectory(targetDir)) {
                // 创建多层目录
                Boolean flag = this.createMultiDir(ftpClient, targetDir);
                if (!flag) {
                    return false;
                }
                ftpClient.changeWorkingDirectory(targetDir);
            }
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 获取源文件夹当前下的文件或目录
            // File[] file = (new File(sourceDir)).listFiles();
            FTPFile[] ftpFiles = ftpClient.listFiles(sourceDir);
            for (int i = 0; i < ftpFiles.length; i++) {
                if (ftpFiles[i].isFile()) {
                    if (null != keyUrlSuffix && !keyUrlSuffix.equals("")) {
                        sourceDir = sourceDir.substring(0, sourceDir.lastIndexOf("/"));
                    }
                    copyFile(ftpFiles[i].getName(), sourceDir, targetDir);//如果是文件,调用复制文件方法复制
                } else if (ftpFiles[i].isDirectory()) {
                    copyDirectiory(sourceDir + "/" + ftpFiles[i].getName(), targetDir + "/" + ftpFiles[i].getName(), keyUrlSuffix);//如果是文件夹,递归
                }
            }
        }
        return true;
    }

/**
     * 复制文件.
     *
     * @param sourceFileName
     * @param sourceDir
     * @param targetDir
     * @throws IOException
     */
    public boolean copyFile(String sourceFileName, String sourceDir, String targetDir) throws IOException {
        ByteArrayInputStream in = null;
        ByteArrayOutputStream fos = new ByteArrayOutputStream();
        int reply = 0;
        reply = ftpClient.getReplyCode();
        try {
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
            } else {
                if (!ftpClient.changeWorkingDirectory(targetDir)) {
                    Boolean flag = this.createMultiDir(ftpClient, targetDir);// 创建多层目录
                    if (!flag) {
                        return false;
                    }
                    ftpClient.changeWorkingDirectory(targetDir);
                }
                //ftpClient.setBufferSize(1024 * 2);
                ftpClient.changeWorkingDirectory(sourceDir);// 变更工作路径   
                ftpClient.enterLocalPassiveMode();
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置以二进制流的方式传输
                ftpClient.retrieveFile(new String(sourceFileName.getBytes("GBK"), "iso-8859-1"), fos);// 将文件读到内存中
                in = new ByteArrayInputStream(fos.toByteArray());
                if (in != null) {
                    ftpClient.changeWorkingDirectory(targetDir);
                    ftpClient.storeFile(new String(sourceFileName.getBytes("GBK"), "iso-8859-1"), in);
                }
            }
        } finally {
            // 关闭流  
            if (in != null) {
                in.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
        return true;
    }

 /**
     * 上传ftp时若传输路径为多层目录创建
     *
     * @param ftpPath
     * @param localDir
     * @param urlSuffix
     */
    @Async
    public boolean uploadDirFiles(String ftpPath, String localDir, String urlSuffix) {
        int reply = 0;
        try {
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
            } else {
                if (!ftpClient.changeWorkingDirectory(ftpPath)) {
                    // 创建多层目录
                    Boolean flag = this.createMultiDir(ftpClient, ftpPath);
                    if (!flag) {
                        return false;
                    }
                    ftpClient.changeWorkingDirectory(ftpPath);
                }
                ftpClient.enterLocalPassiveMode();
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                //InputStream input = new FileInputStream(new File(filePath));
                //ftpClient.storeFile(fileName, input);//上传压缩包
                String fileUrl = this.uploadDirectory(ftpClient, localDir, ftpPath, urlSuffix);

                flag = true;
                System.out.println(fileUrl);
                //input.close();
                ftpClient.logout();
            }
        } catch (Exception e) {
            logger.error("审核时将上传到服务器中的文件读取出来存入ftp文件服务器时出现错误!", e.getMessage());
            throw new BaseException(ExceptionCategory.Illegal_Parameter,
                    "将上传到服务器中的文件读取出来存入ftp文件服务器时出现错误!" + e.getMessage());
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return true;
    }

    /***
     * @上传文件夹
     * @param localDirectory
     *            当地文件夹
     * @param remoteDirectoryPath
     *            Ftp 服务器路径 以目录"/"结束
     * */
    public String uploadDirectory(FTPClient ftpClient, String localDirectory, String remoteDirectoryPath, String urlSuffix) {
        File src = new File(localDirectory);
        String tmpDir = localDirectory.replace("\\", "/").substring(0, localDirectory.replace("\\", "/").lastIndexOf("/"));
        //String childDir = localDirectory.replace("\\", "/").substring(localDirectory.replace("\\", "/").lastIndexOf("/"), localDirectory.replace("\\", "/").length());
        try {
            boolean isT = ftpClient.changeWorkingDirectory(remoteDirectoryPath);// 改变工作路径
            if (!isT) {
                this.createMultiDir(ftpClient, remoteDirectoryPath);
// logger.info(remoteDirectoryPath + "创建文件夹成功!");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        File[] allFile = src.listFiles();
        if (allFile != null) {
            for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
                if (!allFile[currentFile].isDirectory()) {
                    String srcName = allFile[currentFile].getPath().toString();
                    String tempPath = allFile[currentFile].getParent().toString().replace("\\", "/").replace(tmpDir.replace("\\", "/"), "");

//此处的判断是因为文件夹特殊的结构:文件中包括一个index.html文件和三个包含文件的文件夹,都要保存在特定的版本文件夹下,可根据自己文件夹的结构做特殊处理
                    if (srcName.indexOf("index.html") >= 0 && flag == true) {
                        fileUrl = remoteDirectoryPath + "/" + ShortUrlUtil.getShortUrl(remoteDirectoryPath) + urlSuffix;
                        //String newSrcName= srcName.substring(0, srcName.lastIndexOf("\\"))+"\\"+urlSuffix;
                        this.uploadFile(ftpClient, new File(srcName), remoteDirectoryPath, urlSuffix);
                        flag = false;
                    } else {
                        this.uploadFile(ftpClient, new File(srcName), remoteDirectoryPath + tempPath, urlSuffix);
                    }
                } else {
                    uploadDirectory(ftpClient, allFile[currentFile].getPath().toString(), remoteDirectoryPath, urlSuffix);//是文件夹则迭代
                }
            }
        } else {
            this.uploadFile(ftpClient, new File(localDirectory), remoteDirectoryPath, urlSuffix);
            fileUrl = remoteDirectoryPath + localDirectory.substring(localDirectory.lastIndexOf("/"), localDirectory.length());
        }
        return fileUrl;
    }

  /***
     * 上传Ftp文件
     *
     * @param localFile
     *            当地文件
     * @param romotUpLoadePath 上传服务器路径
     *            - 应该以/结束
     * */
    public boolean uploadFile(FTPClient ftpClient, File localFile, String romotUpLoadePath, String urlSuffix) {
        BufferedInputStream inStream = null;
        boolean success = false;
        try {
            try {
                boolean isT = ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
                if (!isT) {
                    this.uploadDirectory(ftpClient, romotUpLoadePath);
                    ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            inStream = new BufferedInputStream(new FileInputStream(localFile));
            if (localFile.getName().equals("index.html")) {
                success = ftpClient.storeFile(urlSuffix, inStream);
            } else {
                success = ftpClient.storeFile(localFile.getName(), inStream);
            }
            if (success == true) {
                return success;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return success;
    }

上边几个方法中用到的工具类:如创建多层目录等:

    /**
     * 创建多层目录
     *
     * @param ftpClient
     * @param multiDir
     * @return
     * @throws IOException
     */
    public boolean createMultiDir(FTPClient ftpClient, String multiDir) throws IOException {
        boolean bool = false;
        String[] dirs = multiDir.split("/");
        ftpClient.changeWorkingDirectory("/");
        for (int i = 1; dirs != null && i < dirs.length; i++) {
            if (!ftpClient.changeWorkingDirectory(dirs[i])) {
                if (ftpClient.makeDirectory(dirs[i])) {
                    if (!ftpClient.changeWorkingDirectory(dirs[i])) {
                        return false;
                    }
                }
            }
            bool = true;
        }
        return bool;
    }

public boolean uploadDirectory(FTPClient ftp, String localDirectory) {
        String remoteDirectoryPath = "";
        // 登录FTP
        try {
            String[] mk = localDirectory.split("/");
            for (int i = 0; i < mk.length; i++) {
                try {
                    remoteDirectoryPath = remoteDirectoryPath + mk[i] + "/";
                    boolean flag = ftp.changeWorkingDirectory(remoteDirectoryPath);
                    if (!flag) {
                        ftp.makeDirectory(remoteDirectoryPath);
                    }
                } catch (IOException e) {
                    return false;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值