场景
聊天室功能,需要定期删除msyql中一个月之前的数据以及磁盘上存储的语音等文件。
磁盘下存储的文件按照年月日分目录存储,所以可以扫描指定目录下所有的文件并获取每个
文件的创建时间进行比较并删除。
文件的上传和按照时间目录存储直接采用如下开发框架自带方法
若依前后端分离版本地搭建开发环境并运行项目的教程:
实现
1、删除mysql中一个月之前的消息记录
<delete id="deleteChatRoomMessageBeforeOneMonth" >
DELETE FROM chat_room_message where date_add(curdate(),INTERVAL -1 month) > send_time;
</delete>
其中send_time是删除的时间依据,即判断该字段小于当前时间减一个月则删除。
2、通过递归方法获取某磁盘路径下所有文件
/**
*
* @param dirFilePath
* @return
*/
public static List<File> getAllFile(String dirFilePath) {
if (StrUtil.isBlank(dirFilePath))
return null;
return getAllFile(new File(dirFilePath));
}
/**
* 获取指定文件夹下所有文件,不含文件夹里的文件
*
* @param dirFile 文件夹
* @return
*/
public static List<File> getAllFile(File dirFile) {
// 如果文件夹不存在或着不是文件夹,则返回 null
if (Objects.isNull(dirFile) || !dirFile.exists() || dirFile.isFile())
return null;
File[] childrenFiles = dirFile.listFiles();
if (Objects.isNull(childrenFiles) || childrenFiles.length == 0)
return null;
List<File> files = new ArrayList<>();
for (File childFile : childrenFiles) {
// 如果是文件,直接添加到结果集合
if (childFile.isFile()) {
files.add(childFile);
}
//以下几行代码取消注释后可以将所有子文件夹里的文件也获取到列表里
else {
// 如果是文件夹,则将其内部文件添加进结果集合
List<File> cFiles = getAllFile(childFile);
if (Objects.isNull(cFiles) || cFiles.isEmpty()) continue;
files.addAll(cFiles);
}
}
return files;
}
3、获取某个文件的创建时间
Files.readAttributes(Paths.get(file.getAbsolutePath()), BasicFileAttributes.class).creationTime()
4、使用stream的filter方法过滤一个月之前创建的文件
list.stream().filter(file -> {
try {
return new Date().getTime() - Files.readAttributes(Paths.get(file.getAbsolutePath()), BasicFileAttributes.class).creationTime().toMillis()>1000*60*60*24*17;
} catch (IOException e) {
e.printStackTrace();
}
return false;
})
5、将一个月之前的文件遍历删除
list.stream().filter(file -> {
try {
return new Date().getTime() - Files.readAttributes(Paths.get(file.getAbsolutePath()), BasicFileAttributes.class).creationTime().toMillis()>1000*60*60*24*17;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}).forEach(file -> {
try {
Files.deleteIfExists(Paths.get(file.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
});
6、定时任务实现
启动类添加@EnableScheduling注解
@SpringBootApplication
@EnableScheduling
public class ImserverApplication {
public static void main(String[] args) {
//SpringApplication.run(ImserverApplication.class, args);
}
}
定时任务配置类添加@Configuration注解并在具体执行的方法中添加@Scheduled注解并配置cron表达式
完整示例代码
package com.chrisf.task;
import cn.hutool.core.util.StrUtil;
import com.chrisf.config.RuoYiConfig;
import com.chrisf.mapper.ChatRoomMessageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Configuration
public class DeleteVoiceFileTask {
@Autowired
private ChatRoomMessageMapper chatRoomMessageMapper;
@Scheduled(cron = "0 0 0 * * ?")
public void testSchedule4(){
//删除聊天室消息中一个月之前的数据
chatRoomMessageMapper.deleteChatRoomMessageBeforeOneMonth();
//删除磁盘录音文件
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
List<File> list = getAllFile(filePath);
list.stream().filter(file -> {
try {
return new Date().getTime() - Files.readAttributes(Paths.get(file.getAbsolutePath()), BasicFileAttributes.class).creationTime().toMillis()>1000*60*60*24*30;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}).forEach(file -> {
try {
Files.deleteIfExists(Paths.get(file.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
});
}
/**
*
* @param dirFilePath
* @return
*/
public static List<File> getAllFile(String dirFilePath) {
if (StrUtil.isBlank(dirFilePath))
return null;
return getAllFile(new File(dirFilePath));
}
/**
* 获取指定文件夹下所有文件,不含文件夹里的文件
*
* @param dirFile 文件夹
* @return
*/
public static List<File> getAllFile(File dirFile) {
// 如果文件夹不存在或着不是文件夹,则返回 null
if (Objects.isNull(dirFile) || !dirFile.exists() || dirFile.isFile())
return null;
File[] childrenFiles = dirFile.listFiles();
if (Objects.isNull(childrenFiles) || childrenFiles.length == 0)
return null;
List<File> files = new ArrayList<>();
for (File childFile : childrenFiles) {
// 如果是文件,直接添加到结果集合
if (childFile.isFile()) {
files.add(childFile);
}
//以下几行代码取消注释后可以将所有子文件夹里的文件也获取到列表里
else {
// 如果是文件夹,则将其内部文件添加进结果集合
List<File> cFiles = getAllFile(childFile);
if (Objects.isNull(cFiles) || cFiles.isEmpty()) continue;
files.addAll(cFiles);
}
}
return files;
}
}