当前位置: 首页 > news >正文

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

直接复制粘贴既可!!

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 环境下

​​​​​​​

相关文章:

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

直接复制粘贴既可!! 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.ZoneOff…...

安卓设置混淆后,gson报错解决方法

一,设置开启混淆release {minifyEnabled truezipAlignEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro } 二,混淆的文件中,对gson相关类不进行混淆,否…...

WPF实战项目十四(API篇):登录注册接口

1、新建UserDto.cs public class UserDto : BaseDto{private string userName;/// <summary>/// 用户名/// </summary>public string UserName{get { return userName; }set { userName value;OnPropertyChanged(); }}private string account;/// <summary>…...

10个免费PPT下载资源网站分享

PPT超级市场https://pptsupermarket.com/ PPT超级市场是一个完全免费的PPT模板下载网站&#xff0c;不需要注册登录&#xff0c;点击下载就能直接使用。 叮当设计https://www.dingdangsheji.com/ 叮当设计是一个完全免费的PPT模板下载网站&#xff0c;每一套PPT的质量都很高。除…...

SpringCloud入门——微服务调用的方式 RestTemplate的使用 使用nacos的服务名初步(Ribbon负载均衡)

目录 引出微服务之间的调用几种调用方法spring提供的组件 RestTemplate的使用导入依赖生产者模块单个配置的情况多个配置的情况没加.yaml的报错【报错】两个同名配置【细节】 完整代码config配置主启动类controller层 消费者模块进行配置restTemplate配置类controller层 使用na…...

Python基础篇(16):python中__new__方法

一、__new__方法的定义 __new__() 方法是一种负责创建 类实例 的 静态方法 二、__new__方法的作用 在内存中为对象分配空间返回对象的引用 三、__new__方法的使用 创建对象时自动调用__new__方法&#xff0c;并且是在__init__初始化方法之前被调用Python解释器获得对象的引…...

linux并发服务器 —— 文件IO相关函数(三)

文件IO 以内存为主体&#xff0c;看待输入输出&#xff1b; 标准C库IO函数带有缓冲区&#xff0c;效率较高&#xff1b; 虚拟地址空间 虚拟地址空间是不存在的&#xff0c;一个应用程序运行期间对应一个虚拟地址空间&#xff1b; 虚拟地址空间的大小由CPU决定&#xff0c;位…...

matlab使用教程(27)—微分代数方程(DAE)求解

1.什么是微分代数方程&#xff1f; 微分代数方程是一类微分方程&#xff0c;其中一个或多个因变量导数未出现在方程中。方程中出现的未包含其导数的变量称为代数变量&#xff0c;代数变量的存在意味着您不能将这些方程记为显式形式 y ′ f t , y 。相反&#xff0c;您可以…...

vue3组合式api <script setup> props 父子组件的写法

父组件传入子组个的变量&#xff0c; 子组件是无法直接修改的&#xff0c; 只能通过 emit的方式&#xff0c; 让父组件修改&#xff0c; 之后子组件更新 <template><div class"parent">我是父组件<son :msg"msg" :obj"obj" chan…...

Compose - 自定义作用域限制函数

一、概念 在 Compose 中对于作用域的应用特别多。比如 weight 修饰符只能用在 RowScope 或者 ColumnScope 作用域中&#xff0c;item 组件只能用在 LazyListScope 作用域中。 标准库中的作用域函数如 apply()、let() 会以不同方式持有和返回上下文对象&#xff0c;调用它们时 L…...

【Flutter】Flutter 使用 photo_view 实现图片查看器

【Flutter】Flutter 使用 photo_view 实现图片查看器 文章目录 一、前言二、photo_view 简介三、安装与基本使用四、使用 PhotoViewGallery 展示多张图片五、完整示例六、总结 一、前言 大家好&#xff0c;我是小雨青年&#xff0c;今天我要给大家介绍一个在 Flutter 中非常实…...

电脑组装教程分享!

案例&#xff1a;如何自己组装电脑&#xff1f; 【看到身边的小伙伴组装一台自己的电脑&#xff0c;我也想试试。但是我对电脑并不是很熟悉&#xff0c;不太了解具体的电脑组装步骤&#xff0c;求一份详细的教程&#xff01;】 电脑已经成为我们日常生活中不可或缺的一部分&a…...

【云原生之Docker实战】使用Docker部署flatnotes笔记工具

【云原生之Docker实战】使用Docker部署flatnotes笔记工具 一、flatnotes介绍1.1 flatnotes简介1.2 flatnotes特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载flatnotes…...

XSSchallenge1-20

test1 第一题直接在test插入XSS代码即可 test2 第二关对内容进行”“包裹 这里可以采用”>来绕过 test3 代码审计发现这里用了htmlspecialchars函数&#xff0c;这个函数对<>和’ “等进行了转义&#xff0c;这里可以用事件来绕过 test4 这里用了str_replace&a…...

centos 7的超详细安装教程

打开虚拟机&#xff0c;创建一个新电脑 我们选择经典&#xff0c;然后选择下一步 我们选择稍后安装&#xff0c;我们在后面进行改设备 因为centos系统是linux系统的一个版本&#xff0c;所有我们选择linux&#xff0c;版本选择centos 7 64位&#xff0c;然后就是点击下一步 这一…...

代码随想录算法训练营第五十二天 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组

代码随想录算法训练营第五十二天 | 300.最长递增子序列&#xff0c;674. 最长连续递增序列&#xff0c;718. 最长重复子数组 300.最长递增子序列674. 最长连续递增序列718. 最长重复子数组 300.最长递增子序列 题目链接 视频讲解 给你一个整数数组 nums &#xff0c;找到其中最…...

计算机图形软件(三)6-6 小结

小结 这一章概括了图形软件系统的主要特点。某些软件系统&#xff0c;如 CAD 软件包和绘图程序&#xff0c;其为特定应用而设计。另外一些软件系统则提供可以在诸如 C的程序设计语言中使用的一个通用图形子程序库&#xff0c;用来为任何应用生成图片。 ISO和AN…...

Flink常用函数

1、比较函数 <> > > < < 注意&#xff1a;select nullnull; 返回为nullIS NULL 、 IS NOT NULL --非空判断value1 IS DISTINCT FROM value2、value1 IS NOT DISTINCT FROM value2、 --不同于value1 BETWEEN [ ASYMMETRIC | S OR 、AND、NOT boolean…...

stable diffusion实践操作-embedding(TEXTUAL INVERSION)

本文专门开一节写图生图相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 可以理解为提示词的集合&#xff0c;可以省略大量的提示词。后缀safetensors&#xff0c;大小几十kb 正文 1、功能 可以理解为提示词的集合&#xff0…...

代码随想录二刷day03

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣203. 移除链表元素二、力扣707. 设计链表三、力扣206. 反转链表 前言 一、力扣203. 移除链表元素 /*** Definition for singly-linked list.* public…...

Captain AI帮你一次过审,上品不再被驳回!

Ozon上品审核驳回、上架后违规下架&#xff0c;是90%以上卖家都踩过的坑。很多卖家遇到上品问题&#xff0c;会用DeepSeek等通用AI查询规则&#xff0c;却往往因为信息滞后、规则解读错误&#xff0c;反复修改仍无法过审&#xff0c;白白错过新品流量黄金期。一、Captain AI能帮…...

利用NSGA-III算法优化随机森林模型超参数的实践与可视化展示:从理论到实现的全过程解析

利用NSGA-III算法优化机器学习模型 通过Optuna库实现机器学习模型超参数的优化与可视化&#xff0c;通过精心设计的目标函数&#xff0c;将搜索多个超参数空间&#xff0c;最终确定使模型性能最优的参数组合 为了更直观地展示调参过程&#xff0c;最后利用3D曲面图对调参效果进…...

2026届最火的六大AI辅助论文平台实测分析

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 基于自然语言处理技术的智能工具是AI写作软件&#xff0c;它能够辅助用户快速生成各类不同的…...

PostGIS中ST_Area计算面积时单位转换的实用技巧

1. 为什么ST_Area在WGS84坐标系下计算结果不对劲&#xff1f; 第一次用PostGIS的ST_Area函数计算地理围栏面积时&#xff0c;我盯着屏幕上那个小得离谱的数字愣了半天——0.000002&#xff1f;这还没我家卫生间大&#xff01;后来才发现&#xff0c;原来90%的新手都会在这个坑里…...

ugrep布尔搜索实战:使用AND/OR/NOT构建复杂查询

ugrep布尔搜索实战&#xff1a;使用AND/OR/NOT构建复杂查询 【免费下载链接】ugrep Ugrep 4.3: an ultra fast, user-friendly, compatible grep. Ugrep combines the best features of other grep, adds new features, and searches fast. Includes a TUI and adds Google-lik…...

从理论到实践:百川2-13B模型权重加载与推理过程代码解读

从理论到实践&#xff1a;百川2-13B模型权重加载与推理过程代码解读 你是不是也遇到过这种情况&#xff1a;好不容易找到一个开源大模型&#xff0c;比如百川2-13B&#xff0c;兴冲冲地下载下来&#xff0c;结果面对那一堆模型权重文件和复杂的代码&#xff0c;瞬间就懵了&…...

Qt qDebug高级调试技巧:从流式输出到自定义日志格式

1. 流式输出的艺术&#xff1a;让调试信息更优雅 第一次接触Qt的开发者往往会被qDebug的流式输出惊艳到——它比传统的printf风格更符合现代C的编码习惯。我在重构一个老项目时&#xff0c;曾经需要同时输出用户ID、操作类型和时间戳三个变量。用传统方法需要写三行printf&…...

PyTorch 2.8视频生成环境搭建:FFmpeg 6.0+Diffusers开箱即用教程

PyTorch 2.8视频生成环境搭建&#xff1a;FFmpeg 6.0Diffusers开箱即用教程 1. 环境准备与快速验证 在开始视频生成项目前&#xff0c;我们需要确保基础环境已经正确配置。本教程使用的镜像已经预装了所有必要的组件&#xff0c;包括&#xff1a; 核心框架&#xff1a;PyTor…...

【ComfyUI】Qwen-Image-Edit-F2P用于影视概念设计:快速生成角色面部概念图

ComfyUI Qwen-Image-Edit-F2P用于影视概念设计&#xff1a;快速生成角色面部概念图 1. 引言&#xff1a;当AI画笔遇见影视美术 想象一下这个场景&#xff1a;一部新剧的美术指导正在为“饱经风霜的西部枪手”这个角色发愁。导演想要一张能瞬间抓住观众眼球的脸&#xff0c;一…...

Evo-1两阶段训练拆解:如何像“冻住”VLM backbone一样,保住你的模型语义不漂移?

Evo-1两阶段训练拆解&#xff1a;如何像“冻住”VLM backbone一样&#xff0c;保住你的模型语义不漂移&#xff1f; 当你尝试将一个预训练的视觉语言模型&#xff08;VLM&#xff09;适配到机器人控制任务时&#xff0c;是否遇到过这样的困境&#xff1a;模型在训练集上表现良…...