SpringBoot自定义工具类—基于定时器完成文件清理功能

news2025/1/13 10:22:40

直接复制粘贴既可!!

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.chrono.ChronoLocalDate;
import java.time.format.DateTimeFormatter;

@Component // 表示将该类声明为一个组件,以便能够被Spring容器管理。
public class FileCleanupTask {

    //@Scheduled(cron = "0 0 0 */3 * ?") // 每隔三天凌晨12点触发任务
    //@Scheduled(cron = "0 */1 * * * ?") // 每隔一分钟触发任务
    @Scheduled(cron = "0 */2 * * * *") // 每隔2秒触发任务
    public void cleanupFiles() {
        String directoryPath = "/manage/uploadFile"; // 修改为你的上传文件存放的目录路径
        File directory = new File(directoryPath);

        // 检查目录是否存在
        // LocalDateTime twoMinutesAgo就代表了当前时间减去1分钟之后的时间点。这个时间点用于比较文件的创建时间,如果文件的创建时间早于twoMinutesAgo,则会被删除。
        if (directory.exists() && directory.isDirectory()) {
            //LocalDate threeDaysAgo = LocalDate.now().minusDays(3);
            // LocalDateTime.now():获取当前的日期和时间。.minusMinutes(1):通过调用minusMinutes方法,在当前时间基础上减去1分钟。
            LocalDateTime twoMinutesAgo = LocalDateTime.now().minusMinutes(1);
            deleteOlderFiles(directory, twoMinutesAgo);
        }
    }

    private void deleteOlderDirectories(File directory, LocalDate threeDaysAgo) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 获取文件夹的名称,格式为"yyyy-MM-ddXXX",其中XXX为随机数
                    String folderName = file.getName();
                    String dateString = folderName.substring(0, 10);
                    LocalDate folderDate = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

                    // 如果文件夹日期早于三天前的日期,则删除文件夹及其内容
                    if (folderDate.isBefore(threeDaysAgo)) {
                        deleteDirectory(file);
                        System.out.println("Deleted directory: " + file.getAbsolutePath());
                    }
                }
            }
        }
    }


    private void deleteOlderFiles(File directory, LocalDateTime twoMinutesAgo) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 获取文件夹的名称,格式为"yyyy-MM-ddXXX",其中XXX为随机数
                    String folderName = file.getName();
                    String dateString = folderName.substring(0, 10);
                    LocalDate folderDate = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    // 如果文件的创建时间早于两分钟前,则删除文件
                    if (folderDate.isBefore(ChronoLocalDate.from(twoMinutesAgo))) {
                        deleteDirectory(file);
                        System.out.println("Deleted file: " + file.getAbsolutePath());
                    }
                }
            }
        }
    }

    private LocalDateTime getCreationDateTime(File file) {
        long fileTimestamp = file.lastModified();
        return LocalDateTime.ofEpochSecond(fileTimestamp / 1000, 0, ZoneOffset.UTC);
    }

    private void deleteDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        directory.delete();
    }
}

说明: 

①、不要自己去写cron表达式,使用在线Cron表达式生成器 (pppet.net)

②、 记得还要在启动类上添加 @EnableScheduling // 启用定时任务,定时删除服务器上的文件

③、注意要删除的文件夹类型(文件夹名称由日期和三位随机数组成,不包含日期删除不了)

④、文件路径的理解

import java.io.File;

public class DirectoryExistsTest {
    public static void main(String[] args) {
        String directoryPath = "/manage/uploadFile"; // 相对路径
        File directory = new File(directoryPath);

        // 判断目录是否存在
        if (directory.exists() && directory.isDirectory()) {
            System.out.println("目录 " + directory.getAbsolutePath() + " 存在。");
        } else {
            System.out.println("目录 " + directory.getAbsolutePath() + " 不存在或不是一个目录。");
        }
    }
}

         通过这个测试类可以发现,String directoryPath = "manage/uploadFile";生成的是目录 E:\excelreport\manage\uploadFile 不存在或不是一个目录,但是目录 E:\manage\uploadFile 存在。

        其实,manage/uploadFile 是一个相对路径,它相对于当前工作目录。Java程序在执行时,会有一个当前工作目录,这取决于您运行程序所在的位置。例如,如果您的 Java 程序文件位于 E:\excelreport 文件夹下,那么当前工作目录将是 E:\excelreport

/manage/uploadFile 是一个绝对路径,它表示从系统的根目录开始的完整路径。在 Windows 系统中,根目录通常是硬盘的根目录,比如 C:\D:\,而在 Linux 系统中,根目录表示为 /

所以,使用相对路径时,它会将当前工作目录与相对路径拼接起来形成完整路径;而使用绝对路径时,它表示从根目录开始的完整路径。

⑤、判读文件目录是否存在 directory.exists() && directory.isDirectory()  的理解

  directory.exists()方法用于判断指定的目录是否存在。点击directory.exists()方法的源码可以看到:

        首先,通过System.getSecurityManager()方法获取SecurityManager对象,如果存在安全管理器,则调用security.checkRead(path)检查是否具有读取目录的权限。

        接下来,调用isInvalid()方法检查当前File对象是否是无效的(例如由于路径名为空等原因)。如果是无效的,则直接返回false表示目录不存在。

        然后,通过调用fs.getBooleanAttributes(this)方法获取指定目录的文件系统属性,其中fsFileSystem对象。获取到的属性值可以使用位掩码进行判断。

        最后,将获取到的属性值与FileSystem.BA_EXISTS进行按位与操作,如果结果不为0,则表示目录存在,返回true;否则表示目录不存在,返回false。综上所述,directory.exists()方法通过检查路径的有效性和获取文件系统属性来判断指定的目录是否存在。

同理,isDirectory()方法用于判断当前File对象是否表示一个目录。该方法的实现如下:

        首先,通过System.getSecurityManager()方法获取SecurityManager对象,如果存在安全管理器,则调用security.checkRead(path)检查是否具有读取目录的权限。

        接下来,调用isInvalid()方法检查当前File对象是否是无效的(例如由于路径名为空等原因)。如果是无效的,则直接返回false表示不是一个目录。

        然后,通过调用fs.getBooleanAttributes(this)方法获取当前File对象的文件系统属性,其中fsFileSystem对象。获取到的属性值可以使用位掩码进行判断。

        最后,将获取到的属性值与FileSystem.BA_DIRECTORY进行按位与操作,如果结果不为0,则表示是一个目录,返回true;否则表示不是一个目录,返回false。综上所述,isDirectory()方法通过检查路径的有效性和获取文件系统属性来判断当前File对象是否表示一个目录。

⑤、删除文件(文件夹)方法的理解:

private void deleteDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        directory.delete();
    }

         这段代码中使用的是Java中的File类和递归方法来删除指定目录下的所有文件和子目录。

        首先,使用绝对路径/manage/uploadFile创建一个File对象表示目录。然后通过directory.exists()directory.isDirectory()方法判断目录是否存在并且是一个目录。

        接下来,使用directory.listFiles()方法获取目录下的所有文件和子目录,返回一个File数组。如果数组不为空,则使用循环遍历数组中的每个元素。

        对于每个元素,首先判断是否是一个目录,如果是目录,则递归调用deleteDirectory()方法,传入当前目录作为参数,实现深度优先的删除操作,即先删除子目录中的内容。

        如果元素不是目录,而是一个文件,则调用file.delete()方法将该文件删除。

        完成对每个文件和子目录的删除后,最后调用directory.delete()方法删除当前目录本身。

        通过递归方式删除目录及其子目录中的所有文件和文件夹,确保在删除父目录之前先删除子目录的内容。最终,整个目录结构都会被完全删除。

运行效果:

window环境下

Linux 环境下

​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/961215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生进阶之PaaS中间件】第一章Redis-2.5缓存持久化

1 Redis持久化 1.1 Redis持久化分类 Redis 中的数据都是保存在内存中的,当Redis服务重启后,内存中的数据都会丢失,所以需要将内存中的数据保存到磁盘上,方便系统故障时,从磁盘上的备份数据恢复到内存中。 Redis 中的持…

PMP考试难度大吗?该如何备考?

PMP(Project Management Professional))认证考试是全球范围内最重要、最权威的项目管理行业认证之一。但是,很多人对PMP考试的难度心存疑虑。在这篇文章中,我们将讨论PMP考试的难度,并提供一些备考建议。 首先&#x…

python“魂牵”京东商品历史价格数据接口(含代码示例)

要通过京东的API获取商品详情历史价格数据,您可以使用京东开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例,展示如何通过京东开放平台API获取商品详情历史价格数据: 首先,确保您已注册成为京东开放平台的开发者…

一款windows的终端神奇,类似mac的iTem2

终于找到了一款windows的终端神奇。类似mac的iTem2 来,上神器 cmder cmder是一款windows的命令行工具,就是我们的linux的终端,用起来和linux的命令一样。所以我们今天要做的是安装并配置cmder ![在这里插入图片描述](https://img-blog.csdni…

前端需要学习哪些技术?

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的同学要注意,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候展现更大的优势。 缺人才,又薪资高,那么怎样才能…

赞奇科技参与华为云828 B2B企业节,云工作站入选精选产品解决方案

8月27日,由华为云携手上万家伙伴共同发起的第二届 828 B2B 企业节拉开帷幕,围绕五大系列活动,为万千中小企业带来精细化商机对接。 聚焦行业数字化所需最优产品,举办超1000场供需对接会,遍及20多个省100多个城市&…

企业架构LNMP学习笔记3

服务器基本环境配置: 1、安装虚拟机,centos7.9 操作系统; 2、网络配置; 3、机器名FQDN设置; 4、DNS解析设置,本地hosts设置; 5、配置yum源环境; 6、vim安装配置; …

windows笔记本远程连接如何打开任务管理器?

参考素材: https://jingyan.baidu.com/article/8275fc86a97f5207a03cf6cd.html https://www.anyviewer.cn/how-to/ctrl-alt-delete-remote-desktop-6540.html 网上查了很多方法,都说ctrlaltend可以解决这个问题。 但是笔记本键盘上没有end键。 继续查了一…

一米脸书营销软件

功能优势 JOIN ADVANTAGE HOME PAGE MARKETING 公共主页营销 可同时对多个账户公共主页评论,点赞等 可批量邀请多个好友对Facebook公共主页进行评论点赞等,也可批量登录小号对自己公共主页进行点赞。 GROUP MARKETING 小组营销 可批量针对不同账户进行…

Altium显示/隐藏白色网络

在Altium软件中,相同网络的单元如果没有连接,会在PCB中出现白色的线,如下图所示。 这些白色的细线用于提示我们还有哪些网络没有布线。 如果我们不想要出现这种线,可以进行如下设置 View > Connections > Hide All 如…

【Unity3D游戏魔坦之争】单例模式管理数据存储【二】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

API是什么?解密API背后的奥秘

API,全称Application Programming Interface,是一种用于不同应用程序间通信的接口,它允许不同的应用程序之间交换数据和功能。API可以理解为应用程序提供给其他应用程序或开发者的接口,通过这个接口,其他应用程序或开发…

连接未来,驱动创新|腾讯云 CODING DevOps 主题沙龙完美收官

点击链接了解详情 近日,由腾讯云 COIDNG 主办的“连接未来,驱动创新”主题沙龙在深圳圆满结束。活动现场,来自不同行业的研效专家汇聚腾讯滨海大厦,共同探讨了在不断变革的市场环境之下,组织研发效能提升的前沿策略与实…

如何做好营销邮件群发?怎么群发电子邮件?

外贸营销邮件群发技巧?邮件营销如何大批量的发送? 营销邮件群发成为了各个企业吸引客户、促进销售的重要手段之一。然而,要想在竞争激烈的市场中脱颖而出,做好营销邮件群发绝非易事。下面将从几个关键方面探讨如何做好营销邮件群发。 营销…

【事务】事务特性、隔离级别、传播属性、失效场景理解及场景模拟

文章目录 事务四大特性通过什么实现特性? 事务隔离级别为什么要设置隔离级别?如何设置隔离级别?事务并发问题模拟?读未提交1.脏读:2.不可重复读:3.幻读: 如何解决事务并发啊? 事务传…

LED显示屏功耗的计算方法

首先,关于户外LED显示屏的功率大小,LED显示屏功率有两种:峰值功率和平均功率。所谓峰值功率主要是指启动时的瞬时电压和电流值以及屏幕全白(显示白色)时的功率,而平均功率则是正常使用情况下的功率。 户外LED显示屏一般功率是多少? 根据产品…

华为Mate 60系列发售,北斗卫星通信技术进一步深入大众消费市场

近日,华为Mate 60系列手机在没有举办发布会的情况下在官方商城突然上架开售,人气火爆。 值得一提的是,华为Mate60 Pro支持卫星通话,无地面网络时,也能拨打和接听卫星电话,还可自由编辑卫星消息。华为 Mate6…

高忆管理:科创50指数逆势上涨 B股放量下挫

8月最后一个交易日,A股三大指数全天震荡调整,科创50指数逆势上涨,盘中涨超1%。到收盘,上证综指报3119.88点,跌0.55%;深证成指报10418.21点,跌0.61%;创业板指报2102.58点,…

MongoDB - 安装

一、Docker安装MongoDB 1. 安装 安装版本: 7.0.0 docker run -itd --name mongodb -v C:\\data\\mongodb\\data:/data/db -p 27017:27017 mongo:7.0.0 --auth-v: 将容器目录/data/db映射到本地C:\\data\\mongodb\\data目录,防止容器删除数据丢失-p: 端口映射--aut…

手写表格OCR识别并与大模型ChatGPT交互?

这是一张手写表格,姓名做了脱敏处理。现在需要对其识别,并分析。 直接粘贴剪切板中的表格原始图片,在网页中ctlV进行识别。识别结果列用分隔符|,可以直接粘贴到excel,进行数据列分隔。为了美观期间,也可以用…