1.问题描述
递归遍历某个路径下的所有文件,找到以某个指定或某类文件,输出其路径,以遍历F盘查找java文件(.java结尾)为例,进行讨论
2.普通实现
最简单的实现就是直接使用递归遍历指定路径
2.1普通实现代码
import java.io.File;
public class AlgorithmFile{
public static void main(String[] args) {
searchFile(new File("F:"));
}
/**
*
* @Description 递归遍历指定路径下的所有文件,并找到以.java结尾的文件
* @param file File对象,提供一个路径
*/
private static void searchFile(File file) {
/**
* 判断是否为文件夹
* 如果是递归遍历
* 如果不是判断是否为.java结尾
* 如果是则输出其绝对路径
*/
if(file.isDirectory()) {
File[] listFiles = file.listFiles();//获取路径下的所有文件(包括文件夹与文件)
if(listFiles != null && listFiles.length > 0) {
for(File f:listFiles) {
searchFile(f);
}
}
}else{
if(file.getName().endsWith(".java")) {
System.out.println(file);
}
}
}
}
2.2运行结果
运行是没有问题的,只是比较慢。
2.3 实现讨论
这样实现确实没有问题,但是如果指定路径下(F盘)的内容很多,就会花费很长时间,要考虑如何提升速度,肯定是多线程,那就用多线程来实现初步的优化。
3.多线程实现
3.1 思路
使用多线程,将不同的子路径交给不同的线程去递归,这样就会达到“多路并进”的效果,大大减少所需的时间,提高效率,但是线程也并非是越多越好,而实际上,在能满足性能需求的前提下,线程是越少越好的,这样可以极大地减少系统资源的开销,而且windows系统中运行的总线程数最好不要超过cpu数目 * 2 + 2 (可以参开Windows多线程编程的相关资料),那么在这里使用线程池来创建指定数目的线程,复用这些线程达到提高效率的作用
3.2代码实现
import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public class AlgorithmFile {
private static ScheduledExecutorService newScheduledThreadPool;
public static void main(String[] args) {
newScheduledThreadPool = Executors.newScheduledThreadPool(10);
newScheduledThreadPool.submit(new MyThread(new File("F:")));
}
private static class MyThread implements Runnable {
private File file;
public MyThread(File file) {
this.file = file;
}
@Override
public void run() {
File[] listFiles = file.listFiles();
if (listFiles != null && listFiles.length > 0) {
for (File f : listFiles) {
if (f.isDirectory()) {
newScheduledThreadPool.submit(new MyThread(f));
} else {
if(f.getName().endsWith(".java")){
System.out.println(new Thread().currentThread().getName() + " : " + file);
}
}
}
}
}
}
}
3.3运行结果
运行速度会比之前快很多,但是代码就会很复杂,使用Lambda表达式与可变参数来进行代码结构的优化
4.使用Lambda表达式与可变参数优化代码结构
4.1基本思路
使用Lambda表达式简化代码结构主要是省略继承Thread或实现Runnable的过程,利用Lambda直接将在run方法中执行的代码提炼出来放在lambda表达式的代码块中,实现多线程
4.2代码实现
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AlgorithmFile {
private static ExecutorService newFixedThreadPool;
public static void main(String[] args) {
File file = new File("F:");
newFixedThreadPool = Executors.newFixedThreadPool(10);
searchFile(file);
}
public static void searchFile(File ... file) {
if(file != null && file.length > 0) {
for(File f : file) {
newFixedThreadPool.submit(() -> {
if(f.isDirectory()) {
searchFile(f.listFiles());
}else{
if(f.getName().endsWith(".java")) {
System.out.println(new Thread().currentThread().getName() + " --- > " + f);
}
}
});
}
}
}
}
4.3运行结果
达到同样的优化目标。
本文探讨了如何使用多线程技术优化文件搜索算法,通过递归遍历指定路径下的所有文件,寻找特定类型的文件(如.java文件),并讨论了单线程与多线程实现的优缺点。
1898

被折叠的 条评论
为什么被折叠?



