1. 删除指定文件夹底下的文件夹及文件
1.1 使用FileUtils删除
- 优点:使用工具类,代码干净,速度快
- 缺点:无法屏蔽一些不想删除或者根据条件删除文件,无法得知删除数量
1.1.1 引入依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
1.1.2 使用
File file = new File("/home/yhc/workSpace/log");
try {
FileUtils.deleteDirectory(file);
} catch (IOException e) {
e.printStackTrace();
}
1.1.3 其他功能
具体查看这位大佬的文章 文件操作工具类:FileUtils
2.1 参数
参数名 | 含义 | 默认值 |
---|---|---|
path | 删除的文件路径,支持多个路径,用 | 分割 |
PATH_PATTERN | 切割路径含有/[或[的正则表达式 | Pattern.compile(“^((?![\\/]\[).)*”) |
RULE_PATTERN | 切割路径含有[的正则表达式 | Pattern.compile(“\[.*”) |
days | 保留天数,超过此天数的文件将被删除 | 30 |
dayTimes | 一天的毫秒数 | 24 * 60 * 60 * 1000 |
ignoreName | 忽略的文件名,多个文件名用;分割 | 123.txt;123.log |
pathRetention | 是否按路径删除文件 | true |
下列为多线程特有参数 | ||
threadNum | 线程池大小 | 2 |
path入参必须含有yyyy mm dd 不区分大小写,/不区分。类似[YYYY]/[YYYYMM]/[YYYYMMDD]、[YYYY]/[MM]/[DD]、[YYYYMMDD]、[YYYY]/[YYYYMM]/[DD]等皆支持
2.2 代码(单线程)
package com.api.apidemo.tool.file;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author yhc
* @description 批量删除文件-普通方式
*/
public class BatchDeleteFile {
/**
* 删除的文件路径,支持多个路径,用|分割
*/
public static final String path = "/home/cathay10/workSpace/log/[yyyyMMdd]";
/**
* 切割路径含有/[或\[的正则表达式
*/
public static final Pattern PATH_PATTERN = Pattern.compile("^((?![\\\\/]\\[).)*");
/**
* 切割路径含有[的正则表达式
*/
public static final Pattern RULE_PATTERN = Pattern.compile("\\[.*");
/**
* 保留天数,超过此天数的文件将被删除
*/
public static final int days = 30;
/**
* 一天的毫秒数
*/
public static final int dayTimes = 24 * 60 * 60 * 1000;
/**
* 忽略的文件名,多个文件名用;分割
*/
public static final String ignoreName = "123.txt;123.log";
/**
* 是否按路径删除文件
*/
public static final boolean pathRetention = true;
public static void main(String[] args) {
long begin = System.currentTimeMillis();
long num = batchDeleteFile();
// 打印总删除文件数
long stop = System.currentTimeMillis();
System.out.println("执行结束,耗时:" + (stop - begin) + "ms" + " 删除文件数量:" + num);
}
/**
* 批量删除文件
*/
public static long batchDeleteFile() {
// 删除数量
long num = 0;
// 删除路径集合 有需要可以添加多个路径,按 | 分割
List sourceList = Arrays.asList(path.split("\\|"));
int length = sourceList.size();
if (length > 0) {
for (int m = 0; m < length; m++) {
// 判断目录是否含有日期格式
String targetPath = replaceDate(sourceList.get(m).toString());
// 处理通配符,将路径中的通配符替换为正则表达式
targetPath = replaceWildcard(targetPath);
if (pathRetention) {
// 按日期格式路径删除文件
// 截取掉除了年月日之外的路径
String dirPath = pathSplit(sourceList.get(m).toString());
File dir = new File(dirPath);
if (dir.exists()) {
// 当前日期
LocalDate nowDate = LocalDate.now();
String rule = ruleSplit(sourceList.get(m).toString());
num = num + judgeDocumentPath(dir, ignoreName, nowDate, rule);
}
} else {
String dirPath = pathSplit(targetPath);
// 按最后修改时间删除文件
File file = new File(dirPath);
if (file.exists()) {
num = num + judgeDocument(file, ignoreName);
}
}
}
}
return num;
}
/**
* 处理文件路径,替换日期格式占位符为当前日期
*
* @param path 原始路径
* @return 处理后的路径,如果没有找到日期占位符,则返回原路径
*/
public static String replaceDate(String path) {
String targetPath;
if (StringUtils.containsIgnoreCase(path, "[yyyy]/[MM]/[dd]")) {
targetPath = replaceIgnoreCase(path, "[yyyy]/[MM]/[dd]", LocalDate.now().toString().replace("-", "/"));
} else if (StringUtils.containsIgnoreCase(path, "[yyyyMMdd]")) {
targetPath = replaceIgnoreCase(path, "[yyyymmdd]", LocalDate.now().toString().replace("-", ""));
} else {
targetPath = path;
}
return targetPath;
}
/**
* 处理文件路径,将路径中的通配符替换为正则表达式
*
* @param path 原始路径
* @return 处理后的路径,如果没有找到通配符,则返回原路径
*/
public static String replaceWildcard(String path) {
path.replaceAll("\\*", ".*").replaceAll("\\?", ".");
return path;
}
/**
* 获取路径中是否包含日期格式
*
* @param targetPath 路径
* @return 处理后的路径,截取第一次遇到日期格式前的路径,如果没有找到有效的日期格式,则返回原路径
*/
public static String pathSplit(String targetPath) {
Matcher pathMatcher = PATH_PATTERN.matcher(targetPath);
while (pathMatcher.find()) {
if (pathMatcher.group() != null) {
return pathMatcher.group();
}
}
// 没有找到有效的日期
return null;
}
/**
* 获取路径中的日期规则正则
*
* @param targetPath 路径
* @return 规则正则
*/
public static String ruleSplit(String targetPath) {
Matcher ruleMatcher = RULE_PATTERN.matcher(targetPath);
String ruleContent;
while (ruleMatcher.find()) {
ruleContent = replaceCharsInSquareBrackets(ruleMatcher.group());
if (ruleContent != null) {
return ruleContent;
}
}
// 没有找到有效的日期
return null;
}
/**
* 替换方括号内的时间格式字符,分隔符[]
*
* @param str
* @return 替换后的字符串
*/
public static String replaceCharsInSquareBrackets(String str) {
// 正则表达式匹配方括号内的内容
String regex = "\\[(.*?)\\]";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
// 存储原始和替换后的内容
List<String> originalMatches = new ArrayList<>();
List<String> replacedMatches = new ArrayList<>();
// 提取匹配的内容并进行替换
while (matcher.find()) {
originalMatches.add(matcher.group());
String match = matcher.group();
String match2 = match.replace("YYYY", "yyyy").replace("mm", "MM").replace("DD", "dd");
replacedMatches.add(match2);
}
// 将原始字符串分解,然后用替换后的内容替换匹配的子串
StringBuilder replacedStr = new StringBuilder(str);
for (int i = 0; i < originalMatches.size(); i++) {
int startIndex = replacedStr.indexOf(originalMatches.get(i));
int endIndex = startIndex + originalMatches.get(i).length();
replacedStr.replace(startIndex, endIndex, replacedMatches.get(i));
}
return replacedStr.toString().replaceAll("\\[", "").replaceAll("\\]", "");
}
/**
* 替换字符串,不区分大小写
*
* @param original 原始字符串
* @param from 要替换的字符串
* @param to 替换后的字符串
* @return 替换后的字符串
*/
public static String replaceIgnoreCase(String original, String from, String to) {
// 将要查找的字符串转换为正则表达式形式,并添加不区分大小写的标志(?i)
String regex = "(?i)" + Pattern.quote(from);
// 使用正则表达式进行替换
return original.replaceAll(regex, to);
}
/**
* 文件处理
*
* @param file 要处理的文件夹
* @param ignoreName 忽略文件名
* @return 处理的文件数量
*/
public static long judgeDocumentPath(File file, String ignoreName, LocalDate nowDate, String rule) {
long num = 0;
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isDirectory()) {
//调用方法循环完成对文件夹中文件的删除
Pattern PATH_RELE_PATTERN = Pattern.compile(rule.replaceAll("[/\\\\]", "[/\\\\\\\\]").replace("yyyy", "(\\d{4})").replace("MM", "(\\d{2})"