You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.3 KiB
177 lines
5.3 KiB
package com.threecloud.dataserviceyy.util;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.io.File;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
|
|
/**
|
|
* 文件清理工具类
|
|
* 负责清理过期的本地录音文件
|
|
*
|
|
* 【目录结构】
|
|
* vaa-recordings/
|
|
* ├── 340100/ # 地市编码
|
|
* │ ├── 20240101/ # 日期目录
|
|
* │ │ └── <device_uuid>/ # 设备目录
|
|
* │ │ └── xxx.wav
|
|
* │ └── 20240102/
|
|
* │ └── ...
|
|
* ├── 340200/
|
|
* └── .sync-marker/
|
|
*/
|
|
public class FileCleaner {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(FileCleaner.class);
|
|
|
|
/**
|
|
* 默认保留天数
|
|
*/
|
|
private static final int DEFAULT_RETAIN_DAYS = 10;
|
|
|
|
/**
|
|
* 日期格式
|
|
*/
|
|
private static final String DATE_FORMAT = "yyyyMMdd";
|
|
|
|
/**
|
|
* 地市编码正则(6位数字)
|
|
*/
|
|
private static final String CITY_CODE_PATTERN = "\\d{6}";
|
|
|
|
/**
|
|
* 清理指定天数前的本地录音文件
|
|
*
|
|
* 清理逻辑:
|
|
* 1. 遍历 basePath 下地市目录(如 340100, 340200)
|
|
* 2. 遍历每个地市目录下的日期目录(如 20240101)
|
|
* 3. 删除早于 cutoffDate 的日期目录
|
|
*
|
|
* @param basePath 基础路径
|
|
* @param retainDays 保留天数
|
|
*/
|
|
public static void cleanOldFiles(String basePath, int retainDays) {
|
|
File baseDir = new File(basePath);
|
|
if (!baseDir.exists() || !baseDir.isDirectory()) {
|
|
logger.debug("基础目录不存在或不是目录: {}", basePath);
|
|
return;
|
|
}
|
|
|
|
// 获取地市目录列表
|
|
File[] cityDirs = baseDir.listFiles(File::isDirectory);
|
|
if (cityDirs == null || cityDirs.length == 0) {
|
|
logger.debug("目录下没有地市子目录: {}", basePath);
|
|
return;
|
|
}
|
|
|
|
String cutoffDate = calculateCutoffDate(retainDays);
|
|
int totalDeletedCount = 0;
|
|
|
|
for (File cityDir : cityDirs) {
|
|
String cityCode = cityDir.getName();
|
|
|
|
// 跳过非地市目录(如 .sync-marker)
|
|
if (!cityCode.matches(CITY_CODE_PATTERN)) {
|
|
logger.debug("跳过非地市目录: {}", cityCode);
|
|
continue;
|
|
}
|
|
|
|
// 清理该地市下的过期日期目录
|
|
int deletedCount = cleanCityDirectory(cityDir, cutoffDate);
|
|
totalDeletedCount += deletedCount;
|
|
|
|
// 如果地市目录为空,删除地市目录
|
|
if (deletedCount > 0 && isEmptyDirectory(cityDir)) {
|
|
cityDir.delete();
|
|
logger.info("已删除空地市目录: {}", cityDir.getAbsolutePath());
|
|
}
|
|
}
|
|
|
|
if (totalDeletedCount > 0) {
|
|
logger.info("清理完成,共删除 {} 个过期日期目录", totalDeletedCount);
|
|
} else {
|
|
logger.debug("没有需要清理的过期文件");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清理指定地市目录下的过期日期目录
|
|
*
|
|
* @param cityDir 地市目录
|
|
* @param cutoffDate 截止日期
|
|
* @return 删除的目录数
|
|
*/
|
|
private static int cleanCityDirectory(File cityDir, String cutoffDate) {
|
|
File[] dateDirs = cityDir.listFiles(File::isDirectory);
|
|
if (dateDirs == null || dateDirs.length == 0) {
|
|
return 0;
|
|
}
|
|
|
|
int deletedCount = 0;
|
|
for (File dateDir : dateDirs) {
|
|
String dirName = dateDir.getName();
|
|
// 只处理日期格式的目录(如 20240101)
|
|
if (dirName.matches("\\d{8}") && dirName.compareTo(cutoffDate) < 0) {
|
|
if (deleteDirectory(dateDir)) {
|
|
deletedCount++;
|
|
logger.info("已清理过期录音目录: {} (早于 {})", dateDir.getAbsolutePath(), cutoffDate);
|
|
}
|
|
}
|
|
}
|
|
|
|
return deletedCount;
|
|
}
|
|
|
|
/**
|
|
* 检查目录是否为空(不包含任何文件和子目录)
|
|
*
|
|
* @param dir 目录
|
|
* @return 是否为空
|
|
*/
|
|
private static boolean isEmptyDirectory(File dir) {
|
|
File[] files = dir.listFiles();
|
|
return files == null || files.length == 0;
|
|
}
|
|
|
|
/**
|
|
* 清理默认天数(10天)前的文件
|
|
*
|
|
* @param basePath 基础路径
|
|
*/
|
|
public static void cleanOldFiles(String basePath) {
|
|
cleanOldFiles(basePath, DEFAULT_RETAIN_DAYS);
|
|
}
|
|
|
|
/**
|
|
* 递归删除目录
|
|
*
|
|
* @param dir 要删除的目录
|
|
* @return 是否成功删除
|
|
*/
|
|
private static boolean deleteDirectory(File dir) {
|
|
File[] files = dir.listFiles();
|
|
if (files != null) {
|
|
for (File file : files) {
|
|
if (file.isDirectory()) {
|
|
deleteDirectory(file);
|
|
} else {
|
|
file.delete();
|
|
}
|
|
}
|
|
}
|
|
return dir.delete();
|
|
}
|
|
|
|
/**
|
|
* 计算截止日期
|
|
*
|
|
* @param retainDays 保留天数
|
|
* @return 截止日期字符串(yyyyMMdd)
|
|
*/
|
|
private static String calculateCutoffDate(int retainDays) {
|
|
Date cutoffDate = DateUtil.addDayByDate(new Date(), -retainDays);
|
|
return new SimpleDateFormat(DATE_FORMAT).format(cutoffDate);
|
|
}
|
|
}
|
|
|