Gyakorlati alapok II.
Kereső rutinok
A
filekezelő alapok után nézzünk meg egy kissé bonyolultabb algoritmust,
nevezetesen alkossunk egy kereső rutint. A feladat legyen a .java
kiterjesztésű állományok keresése és kiírása adott könyvtárban és ha
lehetséges, akkor alatta is. Ha az utóbbi a helyzet, azaz a kezdő könyvtár
csupán kiindulópontja egy belőle kiinduló, további, faszerkezetű
könyvtárstruktúrának (A Java nyelv
néhány további összetett adattípusa → Fa),
akkor észre kell vennünk a következőt: a keresési mechanizmus alapjában
véve ugyanolyan jellegű, csak a kezdő könyvtár változik mindig.
Tapasztaltabbak erre már rá is bólinthatnak, hiszen az ilyen tevékenység
optimális algoritmusa a rekurzió. A témáról kimerítő részletességgel írunk a
Rekurzió (a tiédet!)
című fejezetcsomagban, de az alábbi algoritmusban is azonnal felfedezhető az
egyik rutin rekurzív jellege: a függvény (listRecursiveSearching())
bizonyos feltételek teljesülése után önmagát hívja meg:
for (File f : files) {
if (f.isDirectory()) {
listRecursiveSearching(f, ending);
}
}
Természetesen minél bonyolultabb egy feladat, annál többféleképpen oldható
meg. Az alábbi implementációban a rekurzív rutin után egy egyszerű kereső
függvényt is beillesztésre került. A 2 algoritmus nagyon nagy valószínűséggel
akkor lesz jó, ha azonos végeredményeket fognak szolgáltatni. A kiválasztott
célkönyvtár az egyik régi projektemé (JDBC),
benne a .java kiterjesztésű állományokat keressük meg és listázzuk ki.
Érdemes a kezdő angolosok számára az angol elnevezéseket gyorsan átvennünk. Az
is igaz, hogy a kód magyar nevekkel is működőképes volna, ám a programozást
annyira az angol nyelv határozza meg, hogy mostanában már én csakis angol
nyelvű implementációkat készítek.
-
directory – könyvtár
-
rootdirectory – gyökérkönyvtár (itt a keresés kiindulási pontja)
-
file – állomány
-
ending – végződés (lehetett volna extention – kiterjesztés is)
-
recursion – rekurzió
-
searching – keresés
-
found - megtalálva
-
path – elérési út
-
dirsBeforeSearching – (a keresésben) hátralévő könyvtárak, állományokat
-
dirBeingSearched – éppen vizsgált könyvtár, állomány
-
sort - rendezés
-
array - tömb
-
queue - sor (speciális és itt jól hasznosítható tulajdonságokkal rendelkező adatszerkezet)
Ráadásként meg kell jegyeznünk, hogy a kód még nem tanult adatszerkezetet tartalmaz (Queue<File> dirsBeforeSearching = new PriorityQueue<>();)...
...erről részletesen olvashatunk a Java Kollekció Keretrendszer (JCF) című fejezetcsomagban.
Nézzük meg a futtatható Java-kódot:
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("Recursive searching");
listRecursiveSearching(new
File("D:\\Java\\Projects\\JDBC\\"), ".java");
System.out.println();
System.out.println("Simple searching");
listSearching(new File("D:\\Java\\Projects\\JDBC\\"),
".java");
}
private static void listRecursiveSearching(File file, String ending) {
System.out.println("Searching in..." +
file.getAbsolutePath());
File[] files = file.listFiles();
Arrays.sort(files);
for (File f : files) {
if (f.isFile() &&
f.getName().endsWith(ending)) {
System.out.println("Found: " + f.getAbsolutePath());
}
}
for (File f : files) {
if (f.isDirectory()) {
listRecursiveSearching(f, ending);
}
}
}
private static void listSearching(File rootDirectory, String ending) {
Queue<File> dirsBeforeSearching = new PriorityQueue<>();
dirsBeforeSearching.add(rootDirectory);
while(!dirsBeforeSearching.isEmpty()) {
File dirBeingSearched =
dirsBeforeSearching.remove();
System.out.println("Searching in..."
+ dirBeingSearched.getAbsolutePath());
for(File f :
dirBeingSearched.listFiles()) {
if(f.isFile()) {
if(f.getName().endsWith(ending)) {
System.out.println("Found: " + f.getAbsolutePath());
}
} else{
dirsBeforeSearching.add(f);
}
}
}
}
}
Végeredmény:
Recursive searching
Searching in...D:\Java\Projects\JDBC
Searching in...D:\Java\Projects\JDBC\.settings
Searching in...D:\Java\Projects\JDBC\bin
Searching in...D:\Java\Projects\JDBC\lib
Searching in...D:\Java\Projects\JDBC\src
Found: D:\Java\Projects\JDBC\src\Auto_csop.java
Found: D:\Java\Projects\JDBC\src\ConnectionFactory.java
Found: D:\Java\Projects\JDBC\src\DAO_Auto_csop.java
Found: D:\Java\Projects\JDBC\src\Main.java
Simple searching
Searching in...D:\Java\Projects\JDBC
Searching in...D:\Java\Projects\JDBC\.settings
Searching in...D:\Java\Projects\JDBC\bin
Searching in...D:\Java\Projects\JDBC\lib
Searching in...D:\Java\Projects\JDBC\src
Found: D:\Java\Projects\JDBC\src\Auto_csop.java
Found: D:\Java\Projects\JDBC\src\ConnectionFactory.java
Found: D:\Java\Projects\JDBC\src\DAO_Auto_csop.java
Found: D:\Java\Projects\JDBC\src\Main.java