[英]Find a file in a directory and sub directories using Java 8
如何在Java 8 中實現算法,給定起始目錄和文件名,在給定目錄或嵌套不超過 5 級的任何子目錄中搜索文件。
例如,考慮以下目錄結構:
Folder 1
Folder 2
Folder 3
Folder 4
Folder 5
Folder 6
nfiles.txt....
MyFile.txt
xfile.txt
filesInFolder4....
filesInFolder3...
.....
該算法應該搜索文件夾 5 中包含的文件,並報告是否存在具有給定文件名的文件?
如何使用Java 8做到這一點?
請看一下Files.find方法。
try (Stream<Path> stream = Files.find(Paths.get("Folder 1"), 5,
(path, attr) -> path.getFileName().toString().equals("Myfile.txt") )) {
System.out.println(stream.findAny().isPresent());
} catch (IOException e) {
e.printStackTrace();
}
我發現解決方案使用Files.find和Files.walk如下:
// Finding a file upto x level in File Directory using NIO Files.find
Path start = Paths.get("/Users/***/Documents/server_pull");
int maxDepth = 5;
try(Stream<Path> stream = Files.find(start,
maxDepth,
(path, attr) -> String.valueOf(path).endsWith(".json"))){
String fileName = stream
.sorted()
.map(String::valueOf)
.filter((path) -> {
//System.out.println("In Filter : "+path);
return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
})
.collect(Collectors.joining());
System.out.println("fileName : "+fileName);
}catch(Exception e){
e.printStackTrace();
}
// Finding a file upto x level in File Directory using NIO Files.walk
Path startWalk = Paths.get("/Users/***/Documents/server_pull");
int depth = 5;
try( Stream<Path> stream1 = Files.walk(startWalk,
depth)){
String walkedFile = stream1
.map(String::valueOf)
.filter(path -> {
return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
})
.sorted()
.collect(Collectors.joining());
System.out.println("walkedFile = "+walkedFile);
}catch(Exception e){
e.printStackTrace();
}
它看起來比walkFileTree更簡單......
我對問題進行了一些深入研究,並找到了一種使用ForkJoinPool以同步方式執行此操作的方法,如下所示:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
public class ForkJoinFolderProcessor {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
MyFolderProcessor hadoop = new MyFolderProcessor("/Users/*****/backups/h/", "log");
MyFolderProcessor t8 = new MyFolderProcessor("/Users/*******/apache-tomcat-9.0.2", "log");
MyFolderProcessor t9 = new MyFolderProcessor("/Users/******/apache-tomcat-8.5.20", "log");
pool.execute(hadoop);
pool.execute(t8);
pool.execute(t9);
do {
System.out.println("---------------------");
System.out.println("Parallelism : "+pool.getParallelism());
System.out.println("Active Threads : "+pool.getActiveThreadCount());
System.out.println("Task Count : "+pool.getQueuedTaskCount());
System.out.println("Steal Count : "+pool.getStealCount());
System.out.println("---------------------");
try
{
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}while((!hadoop.isDone()) || (!t8.isDone()) || (!t9.isDone()));
pool.shutdown();
List<String> results = hadoop.join();
System.out.println("Hadoop: Files found : " + results.size()+" "+results.toString());
results = t8.join();
System.out.println("T8: Files found : " + results.size()+" "+results.toString());
results = t9.join();
System.out.println("T9: Files found : " + results.size()+" "+results.toString());
}
}
class MyFolderProcessor extends RecursiveTask<List<String>>{
private static final long serialVersionUID = 1L;
private final String filepath;
private final String fileExt;
public MyFolderProcessor(String path, String extension) {
this.filepath = path;
this.fileExt = extension;
}
@Override
protected List<String> compute() {
List<String> list = new ArrayList<String>();
List<MyFolderProcessor> tasks = new ArrayList<MyFolderProcessor>();
File file = new File(filepath);
File content[] = file.listFiles();
if(content != null) {
for(File f : content) {
if(f.isDirectory()) {
MyFolderProcessor task = new MyFolderProcessor(f.getAbsolutePath(), fileExt);
task.fork();
tasks.add(task);
}else {
if(checkFile(f.getName()))
list.add(f.getAbsolutePath());
}
}
}
if (tasks.size() > 50) {
System.out.println("tasks ran."+ file.getAbsolutePath()+" "+ tasks.size());
}
addResultsFromTasks(list, tasks);
return list;
}
private void addResultsFromTasks(List<String> list, List<MyFolderProcessor> tasks) {
for (MyFolderProcessor item : tasks) {
list.addAll(item.join());
}
}
private boolean checkFile(String name) {
return name.endsWith(fileExt);
}
}
雖然它是更復雜的解決方案,但它在多線程環境下運行良好。
public static String getAdobeExePath(String basePath, String exeName) {
File[] files = new File(basePath).listFiles();
String foundPath;
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
foundPath = getAdobeExePath(files[i].getAbsolutePath(), exeName);
if (foundPath != null) {
return foundPath;
}
}else {
if (exeName.equals(files[i].getName())) {
return files[i].getAbsolutePath();
}
}
}
return null;
}
這是使用遞歸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.