数据同步服务-语音
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

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);
}
}