java-批量下载文件,并且为每个文件创建文件夹,最后合并成一个压缩包

2023-11-07

前言

通过文件url批量下载文件,并且每一个文件创建一个文件夹,以此分类,最后统一打成一个压缩包


一、代码示例

    public void download(List<DownloadContractFileDTO> list) {
       File templateFile = FileUtils.createTemplateFile("zip");
        // 创建一个临时目录用于保存文件夹和文件
        Path tempDir = null;
        try {
            tempDir = Files.createTempDirectory("tempDir");
            for (DownloadContractFileDTO downloadContractFile : list) {
                String name = downloadContractFile.getContractName();
                String code = downloadContractFile.getContractCode();
                List<String> urlList = downloadContractFile.getContractFileUrl();
                // 创建以keyName为名称的文件夹
                String fileName = FileUtil.getFileSubstring(name);
                Path folderPath = Files.createDirectory(tempDir.resolve(fileName + "_" + code));
                for (String url : urlList) {
                    // 下载PDF文件并保存到文件夹中
                    FileUtil.downloadFile(url, folderPath.resolve(name).toString());
                }

            }
            // 压缩文件夹
            FileUtil.zipDirectory(tempDir.toString(),templateFile);
            log.info("文件下载、压缩!完成");
        } catch (Exception e) {
            AssertUtil.notNull(true, "下载失败");
            log.error("下载失败==={}", e.getMessage());
        } finally {
            if (tempDir != null) {
                FileUtil.deleteFilesInDirectory(tempDir.toFile());
            }
            log.info("文件删除完成!");
        }
    }

文件工具类

@Slf4j
public class FileUtil {

    /**
     * 下载文件
     *
     * @param url      url
     * @param filePath filePath
     * @throws IOException
     */
    public static void downloadFile(String url, String filePath) throws IOException {
        try (BufferedInputStream in = new BufferedInputStream(new URL(url).openStream());
             FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
            byte[] dataBuffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
        }
    }

    /**
     * 压缩文件
     *
     * @param sourceDir   文件
     * @param targetFile 文件
     * @throws IOException
     */
    public static void zipDirectory(String sourceDir, File targetFile) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(targetFile);
             ZipOutputStream zos = new ZipOutputStream(fos);
             Stream<Path> paths = Files.walk(Paths.get(sourceDir))) {
            paths.filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        try {
                            Path relativePath = Paths.get(sourceDir).relativize(path);
                            ZipEntry zipEntry = new ZipEntry(relativePath.toString());
                            zos.putNextEntry(zipEntry);
                            byte[] buffer = new byte[1024];
                            int length;
                            try (InputStream is = Files.newInputStream(path)) {
                                while ((length = is.read(buffer)) > 0) {
                                    zos.write(buffer, 0, length);
                                }
                            }
                            zos.closeEntry();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
        }
    }

    /**
     * @param directory      文件
     */
    public static void deleteFilesInDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteFilesInDirectory(file);
                } else {
                    boolean delete = file.delete();
                    log.info("====delete_file=={},==file=={}", delete, JsonUtils.writeAsJson(file));
                }
            }
        }
        boolean delete = directory.delete();
        log.info("===delete_file=={},==file=={}", delete, JsonUtils.writeAsJson(directory));
    }

    /**
     * 获取文件夹名称
     *
     * @return
     */
    public static String getFileSubstring(String name) {
        if (StringUtils.isBlank(name)) {
            return String.valueOf(System.currentTimeMillis());
        }
        int lastDotIndex = name.lastIndexOf(".");
        if (lastDotIndex != -1) {
            return name.substring(0, lastDotIndex);
        } else {
            return name;
        }
    }
    
    /**
     * 创建临时文件
     */
    public static File createTemplateFile(String fileType) {
        String s = UUID.randomUUID() + "." + fileType;
        String filepath = Thread.currentThread().getContextClassLoader().getResource("").getPath()
                + File.separator + "temp";
        File dir = new File(filepath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return createSubFile(dir, s);
    }

    /**
     * 创建子文件
     *
     * @param parentDir 父文件夹
     * @param filename  子文件名
     */
    public static File createSubFile(File parentDir, String filename) {
        return new File(parentDir.getAbsolutePath() + File.separator + filename);
    }
}

实体Bean

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DownloadContractFileDTO implements Serializable {

    /**
     * 合同code
     */
    private String contractCode;

    /**
     * 合同名称
     */
    private String contractName;

    /**
     * 合同问 url
     */
    private List<String> contractFileUrl;

}```

# 二、最后效果

![在这里插入图片描述](https://img-blog.csdnimg.cn/ffccf00753004ae0a5dced3ec62e89ce.png#pic_center)


---

# 总结
提示:具体根据自己需求修改代码
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java-批量下载文件,并且为每个文件创建文件夹,最后合并成一个压缩包 的相关文章

  • 方法重载。你能过度使用它吗?

    当定义多个使用不同过滤器返回相同形状的数据的方法时 什么是更好的做法 显式方法名称或重载方法 例如 如果我有一些产品并且我正在从数据库中提取 显式方式 public List
  • cygwin有java sdk吗?

    cygwin有java sdk吗 如果有一个使用 cygwin 文件系统和 X windows 进行显示的本机 cygwin 实现 那就太好了 不幸的是我不知道这样的版本 我认为移植 OpenJDK 也需要付出很大的努力 但我还没有尝试过
  • 如何通过两跳 SSH 隧道使用 JProfiler

    我正在尝试将 JProfiler 连接到在我将调用的服务器上运行的 JVMremote 该服务器只能从我的工作站访问 local 通过我将调用的另一台服务器middle 我的计划是将 JProfiler 连接到remote是这样的 安装 J
  • Thymeleaf 和 Spring 的布尔条件

    我想在我的网页中添加错误标志 如何使用 Thymeleaf 检查 Spring 模型属性是 true 还是 false 布尔文字是true and false 使用th if你最终会得到如下代码 div 或者如果您决定选择th unless
  • 打印数组时出错

    我得到这个代码 import java util import java io public class Oblig3A public static void main String args OrdAnalyse O new OrdAna
  • 从 java 类生成 xsd 的实用程序

    我想为以下类生成 xsd public class Node private String value private List
  • LibGDX 闪烁

    我已经使用 LibGDX UI 设置来启动一个项目 我在实现 ApplicationListener 中唯一拥有的是 public void create setScreen new LoadingScreen this 这应该会触发 Lo
  • 在Java中读取制表符分隔的文件

    我有以下代码来读取 Java 中的制表符分隔文件 while str in readLine null if str trim length 0 continue String values str split t System out p
  • 如何在不使用反射的情况下查看对象是否是数组?

    在Java中如何在不使用反射的情况下查看对象是否是数组 如何在不使用反射的情况下迭代所有项目 我使用 Google GWT 所以不允许我使用反射 我很想在不使用反射的情况下实现以下方法 private boolean isArray fin
  • 如何将点击侦听器添加到 Android/Java Textview 中的字符串中?

    我想要完成的是大多数 Twitter 应用程序中的标准操作 在文本视图中 文本字符串中的单词前面可能有 提及或 主题标签 并且它们实际上能够添加点击侦听器这个词启动了另一项活动 有谁知道这是如何实现的 下面我附上了一张示例照片 显示了我想要
  • 最终类中的静态函数是否隐式最终?

    我的问题基本上与this https stackoverflow com q 8766476 3882565一 但这是否也适用于static功能 我想了解 编译器是否处理所有static函数在一个final类为final 是否添加final
  • Java 7 中新的 JNLP 缺少项目警告是怎么回事?

    从 Java 6 切换到 Java 7 后 我的 JNLP 仍然工作正常 但它现在抛出一系列如下错误 Missing Application Name manifest attribute for http blah com app jar
  • 如何使用jdbc驱动编写事务?

    我想使用 jdbc 编写一个事务java 我尝试过这个简单的交易 BEGIN TRANSACTION NL GO NL UPDATE table SET col test where id 1010 NL GO NL COMMIT 我尝试过
  • 什么会导致“IO错误java.net.SocketException:选择失败”?

    我的笔记本电脑上运行一个服务器程序 相同的路由器和相同的代码 它工作正常 客户端可以连接 然而 当我将工作区复制到我的电脑并运行它时 我得到了这样的废话 IO错误java net SocketException 选择失败 这是代码 publ
  • jsch - 发送特殊键(CTRL-C、CTRL-D 等)

    我需要向远程终端发送特殊密钥 如何使用 JSCH 做到这一点 Thanks Walter 尝试发送两个字节 0x03 0x04 Check ASCII 表 http www bbdsoft com ascii html了解更多
  • Spark java:如何处理多部分/表单数据输入?

    我在用spark http sparkjava com 开发网络应用程序 当我想上传文件时出现问题 public final class SparkTesting public static void main final String a
  • 如何管理一个 JInternalFrame 调用另一个 JInternalFrame?

    我有一个带有此代码的 JDesktopPane public class Menu extends JFrame implements ActionListener Creates new form Portada public stati
  • 无法取消 GWT 中的重复计时器

    我正在尝试在 GWT 中安排一个重复计时器 它将每一毫秒运行一次 轮询某个事件 如果发现满意 则执行某些操作并取消计时器 我尝试这样做 final Timer t new Timer public void run if condition
  • 仅当用户开始输入时清除 JavaFX TextField 中的提示文本

    默认行为是当字段获得焦点时 字段中的提示文本将被删除 那是标记在场上的时候 是否可以配置文本字段 以便仅在用户开始输入时删除提示文本 否则 我需要在每个文本字段旁边 上方添加一个标签 以描述其中的值 我知道它有点旧 但我自己也需要它 这仍然
  • 最新版本 6.* Struts2 支持 Tomcat 10 吗? [复制]

    这个问题在这里已经有答案了 最新版本 6 Struts2 支持 Tomcat 10 吗 异常启动过滤器 struts2 java lang ClassCastException class org apache struts2 dispat

随机推荐

  • 【python练习题 02】按身高和体重排队

    题目 某学校举行运动会 学生们按编号 1 2 3 n 进行标识 现需要按照身高由低到高排列 对身高相同的人 按体重由轻到重排列 对于身高体重都相同的人 维持原有的编号顺序关系 请输出排列后的学生编号 输入 两个序列 每个序列由n个正整数组成
  • Q-learning

    学习增强学习有段时间了 也接触了 learning了 但对此理解不是很透彻 知道看到头条文章对一篇 翻译文才对此有了较深的理解 特此copy 望见谅 目录 故事案例 table简介 Q learning 算法 学习动作值函数 action
  • MATLAB中生成随机数方法总结

    好久没用MATLAB了 今天在利用MATLAB进行数据处理时 突然发现自己忘记了该如何产生自己需要的随机数形式 于是又查了一通资料 现对其进行一个简单的总结 供自己和大家以后参考 1 randi 产生均匀分布的伪随机整数 产生一个1至10之
  • linux下查询缺少的依赖文件归属于哪个rpm包

    我们在redhat下使用rpm ivh安装rpm包的时候 经常会报缺少依赖条件的错误 如下 root abc Packages rpm ivh httpd 2 4 6 17 el7 x8664 rpm 错误 依赖检测失败 etc mime
  • 浏览器的跨域问题

    什么导致的浏览器的跨域问题 不同源的ajax请求会导致出现跨域的错误 必须要是ajax请求 并且是不同源的才会出现跨域问题 跨域主要是出现在浏览器阻止了响应的接收 服务器有接收到请求也有发出响应 这里是浏览器存在同源策略 什么是同源 同源是
  • 视频剪辑利器:全能的音视频处理工具

    本次推荐的四个开源项目共同展现了开放 灵活和高效的多媒体处理能力 你可以使用它们进行剪辑 格式转换 添加音频轨道或字幕 甚至通过自动生成字幕来裁剪视频 无论是优化媒体文件 节省存储空间还是创造出令人惊叹的视觉效果 这些项目都将成为你不可或缺
  • (转)知乎-区块链技术:如何赋能供应链创新

    区块链技术 如何赋能供应链创新 佳晨说 可能很多人对区块链技术有一定的了解 这份了解大多数都是来自于比特币这样的一个概念 区块链的本质到底是什么 为什么又能够为供应链创新提供新的动力 因为区块链技术可以在供应链的物流 信息流 资金流和业务流
  • Android 11.0 无源码apk设置默认启动Launcher的相关属性

    目录 1 概述 2 无源码apk设置默认启动Launcher的相关属性的核心类
  • vue中使用vditor(发布,编辑,详情回显、上传图片+粘贴图片回显问题,表情的处理)

    文章目录 1 使用方法 1 html 2 dom 发布和编辑页面 3 详情页面 1 页面 2 引入 3 dom 效果图 补充遗漏的XSS过滤 1 注入脚本 2 过滤方法 3 在input val 中调用 补充防盗链功能 此方法有视觉变化 3
  • 获取和设置tinyMCE 4编辑器的内容

    对于tinymce编辑器是无法通过js进行内容的读写的 必须使用编辑器自身的方法才行 下面是一些方法 希望能对用到的朋友有所帮助 1 如果当前页面只有一个编辑器 获取内容 tinyMCE activeEditor getContent 设置
  • STL中set的基本介绍

    STl中的基本内容 容器 set multiset 在集合中 所有的元素只能出现一次 并且默认按照元素的值从小到大自动排序 set不能通过迭代器来修改元素的值 即set的迭代器是一种const iterator multiset 和 set
  • 从摄影测量到计算机视觉----以SFM算法为例,用python+opencv 实现

    因为这篇公式和图比较多 所以笔者以贴图像的形式来 附上最终的结果图 如果你需要笔者的代码 可以发邮件或者去github 笔者后续会贴上github链接 1 两者之间的关系 摄影测量是研究被摄物体的形状 大小 和相对位置关系的一门学科 计算机
  • 【今日CV 计算机视觉论文速览 第109期】Wed, 1 May 2019

    今日CS CV 计算机视觉论文速览 Wed 1 May 2019 Totally 40 papers 上期速览 更多精彩请移步主页 Segmentations is All You Need 提出了一种无须锚点和非极大值抑制的目标检测方法
  • 【华为OD统一考试B卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • Python打印颜色

    author skate time 2014 09 28 Python打印颜色 格式 033 显示方式 前景色 背景色m 说明 前景色 背景色 颜色 30 40 黑色 31 41 红色 32 42 绿色 33 43 黃色 34 44 蓝色
  • java md5签名首位为0时被忽略

    由于hex加密时0不被解析 即0x0001和0x1在表现上都是1只是占用内存大小不同 而如果数字相同自动0x01和0x1加密出来是一样的 所以0x01无论前面有几个0都会去掉 平常使用MD5加密时 自己封装处理时 常见有2个问题 1 转换为
  • ESP32(MicroPython)摇杆控制舵机

    主程序 橙色 信号线 gt 17 红色 电源正 gt 5V 褐色 电源负 gt GND 导入Pin模块 from machine import Pin import time from servo import Servo from mac
  • Springboot生成二维码

    Springboot生成二维码整合 我们使用两种方式 去生成二维码 但是其实 二维码的生成基础 都是zxing包 这是Google开源的一个包 第一种是使用原始的zxing方式去实现 第二种是使用hutool来实现 hutool其实也是对于
  • 关于source insight提示source insight can't create file的解决方法

    如果运行程序 提示错误 source insight can t create file 原因是安装路径或者project存放的路径中出现了中文 解决的方法挺简单的 在它提示无法创建的文件路径下创建相应的文件夹 然后重新打开程序会出现一大堆
  • java-批量下载文件,并且为每个文件创建文件夹,最后合并成一个压缩包

    前言 通过文件url批量下载文件 并且每一个文件创建一个文件夹 以此分类 最后统一打成一个压缩包 一 代码示例 public void download List