वास्तव में काम करने के लिए कई समाधान कर रहे हैं। मुझे लगता है कि आप एक अनन्य फ़ाइल (या पहले एक) को फ़ाइल नाम से मेल खाने वाली निर्देशिका वृक्ष में पाई जानी चाहिए। यह अनुकूलन की समस्या है क्योंकि समाधानों का पता लगाने के कई तरीके हैं, और हम एक स्वीकार्य समाधान खोजना चाहते हैं।
1- समाधान का उपयोग कर FileUtils.listFiles
public static File searchFileWithFileUtils(final File file, final String fileName) {
File target = null;
if(file.isDirectory()) {
Collection<File> files = FileUtils.listFiles(file, null, true);
for (File currFile : files) {
if (currFile.isFile() && currFile.getName().equals(fileName)) {
target = currFile;
break;
}
}
}
return target;
}
समाधान पुस्तकालय FileUtils
का उपयोग कर, क्योंकि विधि एक उपयुक्त समाधान नहीं है FileUtils#listFiles()
भार सभी निर्देशिका/फ़ोल्डर ट्री (लागत महंगी है!)। हम सब पेड़ पता करने के लिए, हम एक बेहतर एल्गोरिथ्म जो जब फ़ाइल पाया जाता है बंद हो जाता है चुन सकते हैं की जरूरत नहीं है।
2- रिकर्सिव समाधान
public static File searchFileRecursive(final File file, final String search) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
File target = searchFileRecursive(f, search);
if(target != null) {
return target;
}
}
} else {
if (search.equals(file.getName())) {
return file;
}
}
return null;
}
एल्गोरिथ्म परीक्षण करता है, तो फ़ाइल किसी भी फ़ोल्डर के अंदर मौजूद है। यदि नहीं, तो यह वर्तमान फ़ोल्डर के सबफ़ोल्डर की कोशिश करता है ... पुनरावर्ती। अगर फ़ाइल वर्तमान शाखा में नहीं मिली है तो यह एक और उपफोल्डर की कोशिश करता है।
अन्वेषण गहरी है, और 1 के एक गहराई में किसी भी फ़ाइल के लिए एल्गोरिथ्म (पिछले शाखाओं पूरी तरह से प्रकट होते हैं!) पिछले सबफ़ोल्डर के पूरी तरह से जानेंगे। इस एल्गोरिदम में पहली शाखा के अंदर गहरे स्थान में फ़ाइलों के लिए सबसे अच्छा प्रदर्शन है।
मामलों के बहुमत में, फ़ाइल स्थान गहरी नहीं है, तो एक और एल्गोरिथ्म है कि अधिकांश मामलों में काम करता है की खोज करें।
3- सबसे तेजी से समाधान: अन्वेषण गहराई
public static File searchFileByDeepness(final String directoryName, final String fileName) {
File target = null;
if(directoryName != null && fileName != null) {
File directory = new File(directoryName);
if(directory.isDirectory()) {
File file = new File(directoryName, fileName);
if(file.isFile()) {
target = file;
}
else {
List<File> subDirectories = getSubDirectories(directory);
do {
List<File> subSubDirectories = new ArrayList<File>();
for(File subDirectory : subDirectories) {
File fileInSubDirectory = new File(subDirectory, fileName);
if(fileInSubDirectory.isFile()) {
return fileInSubDirectory;
}
subSubDirectories.addAll(getSubDirectories(subDirectory));
}
subDirectories = subSubDirectories;
} while(subDirectories != null && ! subDirectories.isEmpty());
}
}
}
return target;
}
private static List<File> getSubDirectories(final File directory) {
File[] subDirectories = directory.listFiles(new FilenameFilter() {
@Override
public boolean accept(final File current, final String name) {
return new File(current, name).isDirectory();
}
});
return Arrays.asList(subDirectories);
}
प्रत्येक गहराई के लिए से, एल्गोरिथ्म एक ही स्तर के सभी फ़ोल्डर के अंदर फ़ाइल खोज करता है। अगर फ़ाइल नहीं मिली है, तो यह अगले स्तर (गहराई ++) की कोशिश करता है। समांतर अन्वेषण (समरूपता) के कारण, यह समाधान ज्यादातर मामलों में उपयुक्त है।
तुलना:
public class FileLocationFinder {
public static void main(final String[] args) {
String rootFolder = args[0];
String fileName = args[1];
long start = System.currentTimeMillis();
File target = searchFileWithFileUtils(new File(rootFolder), fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
target = searchFileRecursive(new File(rootFolder), fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
target = searchFileByDeepness(rootFolder, fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
}
// Solution with FileUtils#listFiles
//--------------------------------------------
public static File searchFileWithFileUtils(final File file, final String fileName) {
File target = null;
if(file.isDirectory()) {
Collection<File> files = FileUtils.listFiles(file, null, true);
for (File currFile : files) {
if (currFile.isFile() && currFile.getName().equals(fileName)) {
target = currFile;
break;
}
}
}
return target;
}
// Recursive solution
//--------------------------------------------
public static File searchFileRecursive(final File file, final String search) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
File target = searchFileRecursive(f, search);
if(target != null) {
return target;
}
}
} else {
if (search.equals(file.getName())) {
return file;
}
}
return null;
}
// Fastest solution
//--------------------------------------------
public static File searchFileByDeepness(final String directoryName, final String fileName) {
File target = null;
if(directoryName != null && fileName != null) {
File directory = new File(directoryName);
if(directory.isDirectory()) {
File file = new File(directoryName, fileName);
if(file.isFile()) {
target = file;
}
else {
List<File> subDirectories = getSubDirectories(directory);
do {
List<File> subSubDirectories = new ArrayList<File>();
for(File subDirectory : subDirectories) {
File fileInSubDirectory = new File(subDirectory, fileName);
if(fileInSubDirectory.isFile()) {
return fileInSubDirectory;
}
subSubDirectories.addAll(getSubDirectories(subDirectory));
}
subDirectories = subSubDirectories;
} while(subDirectories != null && ! subDirectories.isEmpty());
}
}
}
return target;
}
private static List<File> getSubDirectories(final File directory) {
File[] subDirectories = directory.listFiles(new FilenameFilter() {
@Override
public boolean accept(final File current, final String name) {
return new File(current, name).isDirectory();
}
});
return Arrays.asList(subDirectories);
}
}
परिणाम:
searchFileWithFileUtils: 20186ms | searchFileRecursive: 1134ms | searchFileByDeepness: 16ms
[संपादित करें] तुम भी जावा 8 फ़ाइलें एपीआई का उपयोग कर सकते हैं यह काम कर रहे हैं:
public static File searchFileJava8(final String rootFolder, final String fileName) {
File target = null;
Path root = Paths.get(rootFolder);
try (Stream<Path> stream = Files.find(root, Integer.MAX_VALUE, (path, attr) ->
path.getFileName().toString().equals(fileName))) {
Optional<Path> path = stream.findFirst();
if(path.isPresent()) {
target = path.get().toFile();
}
}
catch (IOException e) {
}
return target;
}
लेकिन निष्पादन समय बेहतर नहीं (994ms) है।
इसके अलावा: आप यहां "ब्रेक लेबल" के बजाय नियमित "ब्रेक" का उपयोग/उपयोग कर सकते हैं। (एक सादा वापसी अभी भी @ chssPly76 अंक के रूप में बेहतर है।) –