SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载

这篇具有很好参考价值的文章主要介绍了SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

临时接到一个需求说让根据按照下面的这个图片的结构来打包下载指定位置下的文件到指定位置!
SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载

实现思路:
  1.把已经实现的树形结构的代码进行调用,拿到他的数据进行创建对应的文件夹
  2.因为结构下方的文件没有特别直观的数据库中的关联关系,所以还需要对于管理关系进行梳理
  3.创建好阶级文件,然后调用网上找的工具类打包成为rar压缩包,然后把路劲交给前端进行调用下载
调用数据,然后传递给创建文件方法进行实现:
/**
 * 打包佐证成果文件,压缩成为压缩包!
 *
 * @param projectId
 * @param departId
 */
@ApiOperation(value = "打包佐证成果文件", notes = "佐证与成果-打包佐证成果文件")
@RequestMapping("/exportZip")
public Result<?> exportZip(@RequestParam(name = "projectId", required = false) String projectId, @RequestParam(name = "departId", required = true) String departId) {
    // 获取树形结构
    Result<List<SelectTreeMoneyModel>> loadAllTreeRoot = this.loadAllTreeRoot(projectId, departId);
    // 下载压缩文件,将获取到的树形结构,传递到实现类进行解析跟实现
    String downloadZipFile = downloadZipFile(loadAllTreeRoot, "佐证跟成果", "/");
    return Result.ok(downloadZipFile);
}
递归的创建子集文件夹,然后调用工具类进行压缩成为压缩包文件,注:删除文件必须捋清楚然后进行使用,其实不删除也只会在指定的位置生成一份,所以我这边没有进行使用!
 /**
 * 递归的创建子集文件夹
 *
 * @param data
 * @param rootFile
 */

private void mkdirsChild(List<SelectTreeMoneyModel> data, File rootFile) {
    for (SelectTreeMoneyModel datum : data) {
        // 创建一个file实例对象,指向文件路径(存放照片的根目录)
        File childs = new File(rootFile, datum.getTitle());
        if (!childs.exists()) {
            childs.mkdirs();
        }
        // 判断如果下面还有子节点,如果有则调用自身
        if (!datum.isLeaf()) {
            mkdirsChild(datum.getChildren(), childs);
        }
        // 如果下面没有子节点,则进行判断下面是否有附件,如果有附件则进行下载到指定的文件夹内。
        List<ProjectResult> results = iProjectResultService.list(new LambdaQueryWrapper<ProjectResult>().eq(ProjectResult::getTypeId, datum.getKey()));
        if (ObjectUtils.isNotEmpty(results)) {
            for (ProjectResult result : results) {
                List<ProjectTaskContent> projectTaskContents = projectTaskContentService.list(new LambdaQueryWrapper<ProjectTaskContent>().eq(ProjectTaskContent::getResultId, result.getId()));
                for (ProjectTaskContent projectTaskContent : projectTaskContents) {
                    // 判断附件表不是空的,则进行下载文件到对应的文件夹下
                    if (ObjectUtils.isNotEmpty(projectTaskContents)) {
                        RestTemplate restTemplate = new RestTemplate();
                        // 配置文件进行读取
                        try {
                            ResponseEntity responseEntity = restTemplate.exchange(url + projectTaskContent.getFilePath(), HttpMethod.GET, null, byte[].class);
                            byte[] fileContent = (byte[]) responseEntity.getBody();
                            // 利用 File 对象,然后使用 getName() 方法获取文件名(不包括路径)。
                            File file = new File(projectTaskContent.getName());
                            String filenameWithoutPrefix = file.getName();
                            Files.write(Paths.get(childs + "\\" + filenameWithoutPrefix), fileContent);
                        } catch (IOException e) {
                            e.getMessage();
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
    }
}
 /**
 * 下载压缩文件
 *
 * @param data       数据集合【key:分类名称,value:照片信息集合(key:照片名称,value:照片下载路径)】
 * @param fileStr    照片存放的文件路径
 * @param zipFileStr 压缩文件的路径(加后缀名)
 */
public String downloadZipFile(Result<List<SelectTreeMoneyModel>> data, String fileStr, String zipFileStr) {
    File rootFile = null;
    String folderPath = null;
    try {
        // 遍历传递进来的数据,然后根据传入的数据进行创建文件夹
        for (SelectTreeMoneyModel selectTreeMoneyModel : data.getResult()) {
            // 创建一个file实例对象,指向文件路径(存放照片的根目录)
            zipFileStr = folderUri + selectTreeMoneyModel.getTitle();
            folderPath = selectTreeMoneyModel.getTitle();
            rootFile = new File(zipFileUri + selectTreeMoneyModel.getTitle());
            if (!rootFile.exists()) {
                // 创建新文件夹,可以多层(mkdir()创建新文件夹,只能创建一层)
                rootFile.mkdirs();
            }
            // 根据判断递归的创建文件夹,如果是false则有子集
            if (!selectTreeMoneyModel.isLeaf()) {
                mkdirsChild(selectTreeMoneyModel.getChildren(), rootFile);
            }
        }
        // 创建文件输出流(zip流对象)【实际创建了zip文件,0kb】
        FileOutputStream fos1 = new FileOutputStream(new File(zipFileStr + ".zip"));
        // 压缩法
        toZip1(rootFile, fos1, true);
        //TODO  删除文件和压缩文件,要保证每次压缩只保存一份最新的存在。 因为是删除文件,所以要慎用
        //delFolder(folderUri + folderPath);
        //delFolder(zipFileStr);
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 拼接返回的压缩包地址
    String urlResult = url + folderPath + ".zip";
    return urlResult;
}

/**
 * 删除文件夹
 *
 * @param folderPath 文件夹完整绝对路径
 */
public static void delFolder(String folderPath) {
    try {
        // 删除目录下所有内容
        delAllFile(folderPath);
        File myFilePath = new File(folderPath);
        //删除空文件夹
        myFilePath.delete();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * 删除指定文件夹下所有文件
 *
 * @param path 文件夹完整绝对路径
 */
public static boolean delAllFile(String path) {
    boolean bea = false;
    File file = new File(path);
    if (!file.exists()) {
        return bea;
    }
    if (!file.isDirectory()) {
        return bea;
    }
    //
    String[] tempList = file.list();
    File temp;
    if (tempList != null) {
        for (String var : tempList) {
            // separator 代替文件或文件夹路径的斜线或反斜线,防止跨平台出现错误
            if (path.endsWith(File.separator)) {
                temp = new File(path + var);
            } else {
                temp = new File(path + File.separator + var);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                //先删除文件夹里面的文件
                delAllFile(path + "/" + var);
                //再删除空文件夹
                delFolder(path + "/" + var);
                bea = true;
            }
        }
    }
    return bea;
}

/**
 * 压缩的递归方法
 *
 * @param sourceFile       源文件
 * @param zos              zip输出流
 * @param fileName         源文件的名称
 * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
 *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
 */
private void compress(File sourceFile, ZipOutputStream zos, String fileName, boolean keepDirStructure) throws IOException {
    byte[] buf = new byte[2 * 1024];
    // 判断是否是一个文件
    if (sourceFile.isFile()) {
        // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
        zos.putNextEntry(new ZipEntry(fileName));
        // 创建文件(即某张图片)的输入流
        try (FileInputStream in = new FileInputStream(sourceFile)) {
            int len;
            // read方法:每调用一次就从FileInputStream流中读取一个字节,并返回下一个数据字节,若已到达末尾,就返回-1。
            while ((len = in.read(buf, 0, buf.length)) != -1) {
                zos.write(buf, 0, len);
            }
            // 实际写入到了zip输出流的zip实体中,还没写到文件中【zip文件时0kb,不能打开,因为流没有关闭】
            zos.closeEntry();
        } catch (IOException e) {
            throw new IOException(e);
        }
    } else {
        // 源文件时目录
        // 获取该目录下所有文件和目录的绝对路径
        File[] listFiles = sourceFile.listFiles();
        // 空目录
        if (listFiles == null || listFiles.length == 0) {
            // 需要保留原来的文件结构时,需要对空文件夹进行处理
            if (keepDirStructure) {
                // 空文件夹的处理
                zos.putNextEntry(new ZipEntry(fileName + "/"));
                // 没有文件,不需要文件的copy
                zos.closeEntry();
            }
        } else {
            // 非空目录
            for (File file : listFiles) {
                if (keepDirStructure) {
                    // 注意:getName()仅得到最后一层的名字,不是路径,所以要加“/”,不然所有文件都跑到压缩包根目录下了
                    compress(file, zos, fileName + "/" + file.getName(), true);
                } else {
                    compress(file, zos, file.getName(), false);
                }
            }
        }
    }
}

/**
 * 压缩成ZIP 方法1:保留多级目录结构
 *
 * @param sourceFile       照片存放路径
 * @param out              压缩文件输出流
 * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
 *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
 */
public void toZip1(File sourceFile, OutputStream out, boolean keepDirStructure) throws IOException {
    long start = System.currentTimeMillis();
    // 创建压缩输出流,java7的新语法:Try-with-resources,会确保异常抛出或者try代码块结束时close流【该流必须实现AutoCloseable类】(若是java7之前的版本,则不会生效)
    try (ZipOutputStream zos = new ZipOutputStream(out)) {
        // 压缩
        compress(sourceFile, zos, sourceFile.getName(), keepDirStructure);
        long end = System.currentTimeMillis();
        System.out.println("压缩完成,耗时:" + (end - start) + " ms");
    } catch (IOException e) {
        throw new IOException(e);
    }
}
最后的实现结果

SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载

SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载文章来源地址https://www.toymoban.com/news/detail-814434.html

      总结: 主要还是要理清楚你的层级关系,
      1.然后在递归的时候一定要递归到最底层,然后根据最底层的数据查找跟附件表有关系的ID进行查找,然后将有关系的文件下载到指定的文件夹下,
      2.然后打包成为压缩包这种实现直接可以进行百度查找到适合自己的工具类,如果不是直接适用,可以进行修改工具类的方法进行适配。

到了这里,关于SpringBoot根据多阶层创建文件,然后压缩成压缩包进行下载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • linux中根据文件的创建时间批量删除文件

    在Ubuntu上,你可以使用`find`命令来根据时间批量删除图片。以下是具体的步骤: 1. 打开终端(Terminal)。 2. 使用以下命令进入你希望删除文件的目录: 将`/path/to/directory`替换为实际存放文件的目录路径。 3. 使用以下命令找到符合条件的文件: 上述命令会列出 当前目录及其子

    2024年02月10日
    浏览(28)
  • C++ minizip的简单使用,zip文件的创建、读取、修改、密码压缩、4G以上大文件压缩。

            兄弟姐妹们好,深夜党又来记录枯燥的编程生活了。今天给大家带来的是minizip库,一个解压和压缩文件的开源代码库,如题目所示的结构来介绍。你可以在下面的链接搜索到minizip库: http://www.winimage.com/zLibDll/minizip.html        github地址: zlib/contrib/minizip at master ·

    2024年02月04日
    浏览(26)
  • 【前端】-vue-对打包的静态文件进行压缩

    通过 npm run build 打包时候,会发现静态文件很大,放在nginx服务中访问页面会很慢,所以可在打包过程中对静态文件再压缩。 对js、css、html等文件进行压缩: 安装插件 “compression-webpack-plugin” 。(我本地版本: cnpm install compression-webpack-plugin@5.0.1) 配置 vue.config.js 文件: 此时运

    2024年01月22日
    浏览(29)
  • Spring Boot实现对超大文件进行异步压缩下载

     在Web应用中,文件下载功能是一个常见的需求,特别是当你需要提供用户下载各种类型的文件时。本文将演示如何使用Spring Boot框架来实现一个简单而强大的文件下载功能。我们将创建一个RESTful API,通过该API,用户可以下载问价为ZIP压缩文件。 首先,确保你已经创建了一个

    2024年02月07日
    浏览(41)
  • SpringBoot实现文件记录日志,日志文件自动归档和压缩

    😊 @ 作者: Eric 💖 @ 主页: https://blog.csdn.net/weixin_47316183?type=blog 🎉 @ 主题: SpringBoot实现文件记录日志,日志文件自动归档和压缩 ⏱️ @ 创作时间: 2023年08月06日 Logback 是一个Java日志框架,它是 log4j 的后继者,被广泛用于应用程序中记录日志。 Logger(日志记录器): L

    2024年02月14日
    浏览(24)
  • 深度学习实战20(进阶版)-文件智能搜索系统,可以根据文件内容进行关键词搜索,快速找到文件

    大家好,我是微学AI,今天给大家带来深度学习实战项目-文件智能搜索系统,文件智能搜索系统是一种能够帮助用户通过文件的内容快速搜索和定位文件的软件系统。 随着互联网和数字化技术的普及,数据和信息呈现爆炸式增长的趋势,文件管理和搜索变得越来越困难。传统

    2024年02月13日
    浏览(36)
  • 【前端】根据后端返回的url进行下载并设置文件下载名称

            在我们项目当中存储文件是存储到厂商的服务器上的,然后厂商返回一个可以直接下载url地址,但是前端使用这个url下载的时候永远都是保存一个名字,这时候我们就需要设置文件保存的名称,         那么如何实现呢?使用了fetch将url转换成了blob即可。 代码

    2024年02月04日
    浏览(43)
  • k8s服务部署核心流程:以Jenkins为核心,从Gitee拉取代码,然后进行maven构建,之后使用docker命令打镜像,并推送镜像到harbor仓库,之后远程调用k8s命令创建服务

    前提是我们在自己电脑上模拟整个流程。 假设我们需要搭建一主一从的k8s集群,那就需要安装VMvare和Centos7(点击我查看安装文档), 然后就可以在这两个虚拟机上搭建k8s集群了(点击我查看安装文档), 一个最简单的devops流程已经在标题中写明了, 其中可以搭建gitlab(点

    2024年02月02日
    浏览(41)
  • 【python脚本】python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存

    我在进行目标检测时候,比如红绿灯检测,目标区域很小,样本杂乱。 想要筛选错误样本的话,很困难。可以把目标区域裁剪出来。人大脑处理对于这样的异己比较敏感。样本量较少的话可以自己筛一筛。样本量较大的话,可以训练一个分类模型帮你筛一下。 它就可以实现

    2024年02月15日
    浏览(34)
  • 通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

    1.简单理解文件下载 文件下载,是从服务器下载到本地电脑。 文件下载的原理,首先通过IO流将服务器的文件读取到内存里(只有将数据读到内存,电脑才可以操作数据),读取后文件数据存放在内存中,将内存中的数据通过网络发送给本地客户端的浏览器。本地客户端的浏

    2024年02月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包