有没有比递归更好的文件搜索算法?
Is there any better file search algorithm than recursion?
我使用递归来搜索特定类型的文件(例如,此处使用的是 .pdf 文件)。
我的递归算法搜索所有子文件夹。
但是我发现当子文件夹太多时它会缺乏性能。子子文件夹,子子子文件夹。
我想知道有没有更好的文件搜索算法
下面是我的文件搜索递归代码。我以 .pdf 文件为例
import java.io.File;
public class FInd {
public static void main(String[] args) {
File f = new File("D:/");
find(f);
}
public static void find(File f){
File []list = f.listFiles();
try{
for(int i=0;i<list.length && list.length>0;i++){
if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
list[i].getName().contains(".PDF"))
System.out.println(list[i].getAbsolutePath());
if(list[i].isDirectory()) find(list[i]);
}
}catch(Exception e){
}
}
}
与文件资源管理器中的搜索选项相比,此代码稍微快一些或等于。我想知道比这个更快的算法
也许你可以使用多线程...
您输入的每个文件夹都会从新线程开始...即使您的线程数比 CPU 多,这也不是问题,因为 Windows 可以 运行 多更多话题...
线程的问题在于启动它们是有成本的,因此文件浏览+递归的增加必须优于 N folders/threads 的额外成本。
这是一个使用循环(递归的经典替代)的简单方法
static boolean avoidRecursion(String target){
File currentDir = new File(System.getProperty("user.home"));
Stack<File> dirs = new Stack<File>();
dirs.push(currentDir);
do{
for(File f : dirs.pop().listFiles()){
if (f.isDirectory())
dirs.push(f);
else{
if (f.getName().equals(target))
return true;
}
}
}while(!dirs.isEmpty());
return false;
}
衡量两种方法并选择更快的选项
尝试迭代方式
public class Find {
public static void main(String[] args) {
File f = new File("D:/");
Stack stack = new Stack<File>();
stack.push(f);
while (!stack.empty())
{
f = (File) stack.pop();
File []list = f.listFiles();
try{
for(int i=0;i<list.length && list.length>0;i++){
if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
list[i].getName().contains(".PDF"))
System.out.println(list[i].getAbsolutePath());
if(list[i].isDirectory()) stack.push(list[i]);
}
}catch(Exception e){
}
}
使用 Files.walk() 方法 returns 一个 Java8 流。您可以使用并行流很容易地并行化该计算。
在尝试使用资源方法中使用以下方便的习惯用法:
try(流值 = Files.walk(rootPath)){
....}
在 rootPath 中,您可以使用 Paths.get("root location") 实际到达根位置。
我使用递归来搜索特定类型的文件(例如,此处使用的是 .pdf 文件)。 我的递归算法搜索所有子文件夹。 但是我发现当子文件夹太多时它会缺乏性能。子子文件夹,子子子文件夹。 我想知道有没有更好的文件搜索算法
下面是我的文件搜索递归代码。我以 .pdf 文件为例
import java.io.File;
public class FInd {
public static void main(String[] args) {
File f = new File("D:/");
find(f);
}
public static void find(File f){
File []list = f.listFiles();
try{
for(int i=0;i<list.length && list.length>0;i++){
if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
list[i].getName().contains(".PDF"))
System.out.println(list[i].getAbsolutePath());
if(list[i].isDirectory()) find(list[i]);
}
}catch(Exception e){
}
}
}
与文件资源管理器中的搜索选项相比,此代码稍微快一些或等于。我想知道比这个更快的算法
也许你可以使用多线程...
您输入的每个文件夹都会从新线程开始...即使您的线程数比 CPU 多,这也不是问题,因为 Windows 可以 运行 多更多话题...
线程的问题在于启动它们是有成本的,因此文件浏览+递归的增加必须优于 N folders/threads 的额外成本。
这是一个使用循环(递归的经典替代)的简单方法
static boolean avoidRecursion(String target){
File currentDir = new File(System.getProperty("user.home"));
Stack<File> dirs = new Stack<File>();
dirs.push(currentDir);
do{
for(File f : dirs.pop().listFiles()){
if (f.isDirectory())
dirs.push(f);
else{
if (f.getName().equals(target))
return true;
}
}
}while(!dirs.isEmpty());
return false;
}
衡量两种方法并选择更快的选项
尝试迭代方式
public class Find {
public static void main(String[] args) {
File f = new File("D:/");
Stack stack = new Stack<File>();
stack.push(f);
while (!stack.empty())
{
f = (File) stack.pop();
File []list = f.listFiles();
try{
for(int i=0;i<list.length && list.length>0;i++){
if(list[i].isFile() && (list[i].getName().contains(".pdf")) ||
list[i].getName().contains(".PDF"))
System.out.println(list[i].getAbsolutePath());
if(list[i].isDirectory()) stack.push(list[i]);
}
}catch(Exception e){
}
}
使用 Files.walk() 方法 returns 一个 Java8 流。您可以使用并行流很容易地并行化该计算。
在尝试使用资源方法中使用以下方便的习惯用法:
try(流值 = Files.walk(rootPath)){ ....}
在 rootPath 中,您可以使用 Paths.get("root location") 实际到达根位置。