目录
- 1 需求
- 2 实现1(第一种方法)
- 2 实现2 (推荐使用这个,快)
- 3 实现3(推荐)
1 需求
现在有一个文件夹,里面会一直存数据,动态的存数据,之后可能会达到100万,1千万数据。
那么为了查询这个文件夹里面2天之内的数据,根据修改时间进行查询,我们如何操作
2 实现1(第一种方法)
/**
* 遍历出一个文件夹下的全部的数据
* */
public static void getAllFile(File fileInput, List<File> allFileList) {
// 获取文件列表
File[] fileList = fileInput.listFiles();
if (!ArrayUtil.isEmpty(fileList)) {
for (File file : fileList) {
if (file.isDirectory()) {
// 递归处理文件夹
// 如果不想统计子文件夹则可以将下一行注释掉
getAllFile(file, allFileList);
} else {
// 如果是文件则将其加入到文件数组中
allFileList.add(file);
}
}
}
}
/**
* 一个文件夹
下前两天的全部的数据
* */
public static List<File> listOrderByDate(String fliePath) {
// 存放的是一个文件夹下的全部的数据
List<File> allFileList = new ArrayList<>();
getAllFile(new File(fliePath), allFileList);
long start = DateUtil.offsetDay(new Date(), -2).getTime();
long end = new Date().getTime();
List<File> collect = allFileList.parallelStream().filter(x -> x.lastModified() > start && x.lastModified() < end).collect(Collectors.toList());
List<File> sortedCollect = collect.stream().sorted((t1, t2) -> Long.compare(t2.lastModified(), t1.lastModified())).collect(Collectors.toList());
return sortedCollect;
}
public static void main(String[] args) {
long beginTime = System.currentTimeMillis();
String psth = "D:\\100w\\dest";
// 遍历文件夹
List<File> files = listOrderByDate(psth);
System.out.println(files.size());
long endTime = System.currentTimeMillis();
long l = endTime - beginTime;
System.out.println(l/1000);
使用上面的方法,72608个文件,大小 都是50MB 左右的文件,花费了15秒
2 实现2 (推荐使用这个,快)
public static void main(String[] args) throws InterruptedException, ExecutionException {
long beginTime = System.currentTimeMillis();
String folderPath = "D:\\100w\\dest"; // 替换为实际的文件夹路径
int numThreads = Runtime.getRuntime().availableProcessors(); // 获取可用的处理器核心数
// 获取当前时间
Date currentDate = new Date();
// 计算两天前的时间
long twoDaysAgoMillis = currentDate.getTime() - 2 * 24 * 60 * 60 * 1000;
// 创建文件对象表示文件夹
File folder = new File(folderPath);
// 获取文件夹下的所有文件
File[] files = folder.listFiles();
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
// 创建任务列表
List<Callable<List<File>>> tasks = new ArrayList<>();
// 将文件列表分成多个子列表
int batchSize = 10000; // 每个子列表的大小
if (files != null) {
for (int i = 0; i < files.length; i += batchSize) {
final int startIndex = i;
final int endIndex = Math.min(i + batchSize, files.length);
// 创建子任务,每个子任务处理一个子列表的文件
Callable<List<File>> task = () -> {
List<File> result = new ArrayList<>();
for (int j = startIndex; j < endIndex; j++) {
File file = files[j];
// 检查文件最后修改时间是否在两天内
if (file.lastModified() >= twoDaysAgoMillis) {
result.add(file);
}
}
return result;
};
tasks.add(task);
}
}
// 提交并行任务
List<Future<List<File>>> futures = executor.invokeAll(tasks);
// 收集结果
List<File> result = new ArrayList<>();
for (Future<List<File>> future : futures) {
result.addAll(future.get());
}
// 关闭线程池
executor.shutdown();
// 处理结果,例如打印文件名
System.out.println(result.size());
long endTime = System.currentTimeMillis();
long l = endTime - beginTime;
System.out.println(l/1000);
获取是1秒
3 实现3(推荐)
public static void main(String[] args) {
long start = System.currentTimeMillis();
String folderPath = "D:\\100w\\dest"; // 替换为实际的文件夹路径
List<File> modifiedFiles = getModifiedFilesWithinTwoDays(folderPath);
System.out.println("修改时间在2天之内的文件数量: " + modifiedFiles.size());
long end = System.currentTimeMillis();
long ss = end - start;
System.out.println(ss/1000);
// 处理修改时间在2天之内的文件数据
}
public static List<File> getModifiedFilesWithinTwoDays(String folderPath) {
List<File> modifiedFiles = new ArrayList<>();
File folder = new File(folderPath);
if (folder.exists() && folder.isDirectory()) {
File[] files = folder.listFiles();
if (files != null) {
Instant twoDaysAgo = Instant.now().minus(Duration.ofDays(2));
for (File file : files) {
try {
BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
Instant lastModifiedTime = attrs.lastModifiedTime().toInstant();
if (lastModifiedTime.isAfter(twoDaysAgo)) {
modifiedFiles.add(file);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return modifiedFiles;
}