Oncelikle fonksiyonumuzun tanımını yapalım:
Function DosyalariBul(yol,aramametni:string):integer;
Burada yol ve aramametni olmak uzere 2 parametre tanımladık. Bunlardan "yol" tahmin edebileceğiniz gibi arama yapılacak yolu belirtirken "aramametni" de Windows'tan aşina olduğumuz "*" karakterinin de kullanabileceğimiz bir arama metnini temsil ediyor. Bunlara ek olarak fonksiyonun başında "bulunan" adında ve "TSearchRec" tipinde bir değişken daha tanımlıyoruz. Bu değişken bulunan dosyaya ait bilgileri tutacak.
var
bulundu:TSearchRec;
İşte şimdi "FindFirst" fonksiyonunu kullanmamız gerekiyor. Burada ufak bir acıklama yapalım hemen. FindFirst bir aramaya başlarken başlangıcta ve sadece bir kere cağırmamız gerekn bir fonksiyondur. Bu fonksiyon parametre olarak aramametni ve yolun birleştirilmiş bir versiyonunu, bulunacak dosyaların ozelliklerini(arşiv, gizli, klasor vs.) ve bulundu adlı kaydımızı parametre olarak alıyor. Donuş değeri "0" ise kriterlerimize uygun bir veya daha fazla dosya bulunduğunu anlıyoruz. Daha sonra kriterimize uyan bir sonraki dosyayı bulmak icin FindNext fonksiyonunu cağırıyoruz. Bu fonksiyon sadece "bulundu" adlı değişkenimizi parametre alıyor. Arama kriterlerini ise FindFirst ile bir kez belirttiğimiz icin tekrar vermemize gerek yok. Yine bu fonksiyondan da donuş değeri olarak "0" değerini alırsak aramamıza devam edebiliriz. O zaman buna uygun bir "repeat-until" dongusu şu şekilde olacak:
if FindFirst(yol+aramametni,faAnyFile,bulundu) = 0 then
begin
repeat
begin
//buraya bulunan dosyayla ilgili yapılacak işlemler girecek
end;
until (FindNext(bulundu) 0);
end; //if'in end'i.
Bu kısmı incelersek, ilk başta ğer kriterimize uygun bir dosya yoksa aramaya girmememizi sağlayan bir IF komutu yer alıyor. Bunun ardından FindNext fonksiyonundan 0'dan farklı bir değer donene kadar; yani uygun başka dosya kalmayana kadar yukarıda belirtilen(repeat ve end arasında kalan) komutları uygula demiş oluyoruz. Bu arada unutmadan "yol" değişkenine girilen değerin sonunda "" işaretinin olamsı gerekyiyor ki sonuna aramam metnini eklediğimizde sorun yaşanmasın.
Bizim fonksiyonumuzun donuş değeri integer cunku biz sadece bulunan dosya sayısını dondureceğiz. Bu yuzden fonksiyonun başında donuş değerimii sıfırlamamız gerekiyor:
result:=0;
Şimdi yukarıda boş bıraktığımız yere
inc(result);
komutunu eklersek fonksiyonumuz işimizi gorecek hale geliyor. Yalnız fonksiyonun bitiminden hemen once
FindClose(bulundu);
yazmamız gerekiyor ki "bulundu" değişkenimiz icin ayrılan bellek serbest bırakılsın.
Tabi ki bu fonksiyonu kullanacak kişiler sadece dosya sayısını istemeyecekler. O zaman biraz daha detaya girelim ve "TSearchRec" tipinin dosyaya ait ne gibi bilgiler icerdiğine bir goz atalım. Bu bir kayıt tipi olduğu icin icinde altbirimler var. Bu birimlerin isimleri, tipleri ve ne gibi bilgiler icerdikleri aşağıda:
Time: Integer;
Bu, adından da anlaşılacağı uzere dosyanın zaman ve tarih bilgisini tutuyor. Bu bilgi dosyanın son değiştirilme tarihini Delphi'nin zaman formatında saklıyor.
Size: Integer;
Yine adından anlaşılacağı uzere bu da dosyanın boyut bilgisini iceriyor. Yalnız burada dikkat edilmesi gereken nokta bu bilginin kesin doğru olmayabileceği. Cunku artık doya boyutları 64-bit'lik sayıalr da olabiliyorlar ve bu "Integer" tipinde yani 32-bit'lik bir değişken.
Attr: Integer;
Bu değişken ise dosyanın oznitelik bilgisini saklıyor. Integer tipinde tanımlanmış olmasına rağmen Delphi size anlaşılır isimlere sahip sabitler sunuyor. Yani gizli dosyanın oznitelik değeri kactı diye hatırlamanıza gerek kalmıyor. Buraya gireceğiniz sabitleri veya değerleri "FindFirst" fonksiyonunun dosya tipi boumunde de kullanabilirsiniz. Şimdibu sabitlere bir bakalım:
faReadOnly : Bu "Salt Okunur" ozniteliğini temsil ediyor. Sayısal değeri "1".
faHidden : Bu ise "Gizli" ozniteliğini temsil ediyor. Sayısal değeri "2".
faSystem : "sistem Dosyası" ozniteliğni temsil eder. Sayısal değri "4".
faVolumeID : "Surucu tanılama dosyası" ozniteliğini temsil eder. Sayısal değeri "8".
faDirectory : Bulunan oğenin bir klasor olduğunu belirtir. Sayısal değeri "16".
faArchive : "Arşiv" ozniletiliğini belirtir. Sayısal değeri "32".
faSymLink : Bulunan oğrenin sembolikbir bağlantı olduğunu gosterir(ben de bilmiyorum ne olduğunu

faAnyFile : Bunu bulunan dosyalara bakarken kullanmaktan cok arama yaparken her tipteki dosyanın buunmasını sağlamak icin FindFirst fonksiyonunda kullanmak bir anlam ifade ediyor. Her turlu dosya tpini temsil ediyor. Sayısal değeri "71".
Şimdi burada o kadar sabit değerden bahsettim flan ama biz bulduğumuz oğenin buozelliklere sahip olup olamdığın nasıl anlayacağız? Şoyle ki eğer "Attr" bilgisini istediğimiz ozelliğin değeri ile "AND" işleminden gecirdiğimizde sonuc sıfırdan buyuk oluyorsa bu ozellik oğede var demektir. Bir ornekle daha da acıklığa kavuşturalım olayı:
if (bulundu.Attr AND faDirectory) > 0 then ....
Burada eğer bulunan oğre bir klasor ise "then" kısmından sonragelen komut(lar) calıştırılır. Sanırım yeteri kada acıklayıcı oldu. Bu işlemi sadece bir sabitle değil birden cok sabitle de yapabilirsiniz. (bulundu.Attr AND faDirectory AND FaArchive; gibi).
Name: TFileName;
Tipinin TFileName olmasına bakmayın o aslında bir string

Evet işte bitirdik. Son olarak bu fonksiyon arama yaptığınız klasorun alt klasorlerine bakmaz. Eğer bunu yapmasını istiyorsak o zaman fonksiyonumuzun kendi kendisini cağırmasını sağlamalıyız. Buna dabir ornek yazalım ve bu yazımıza da son noktayı yada noktalı virgulu(!) koyalım

Function DosyalariBul(yol,aramametni:string):integer;
var
bulundu:TSearchRec;
begin
result:=0;
if FindFirst(yol+aramametni,faAnyFile,bulundu) = 0 then
begin
repeat
begin
if (bulundu.Attr AND faDirectory) > 0 then result:=result+DosyalariBul(yol+buldu.Name+'',ara mametni)
else inc(Result);
end;
until (FindNext(bulundu) 0);
end;
FindClose(bulundu);
end;
Fonksiyonumuzun son hali boyle olmalı. Burada gorduğunuz gibi once oğenin klasor olup olmadığına bakılıyor; eğer klasor ise bu sefer fonksiyonumuzdan bir tane daha cağırıyoruz. Burada fark yeni cağırılan haline parametre olarak ilk yolun değil ilk yol + bulunan klasor'un verilmesi. Daha sonra buradan donen dosya sayısını ana sayacımıza ekliyoruz. Burada dikkat etmenizi istediğimbir nokta daha var; fonksiyonumuz bu haliyle bir klasorun icindeki TUM altklasorlere kadar inebiliyor. Cunku yeni parametrelerle cağırılan fonkiyonumuz bir klasor bulduğunda kendini daha yeni parametrelerle tekrar cağırıyor. Burada kafanızın karışmaması icin fonksiyonu her cağırdığımızda o cağrıya ozel bir bellek alanını kullandığını unutmamanız. Yani cağrıyı yapan fonksiyondan bağımsız bir şekilde calışıyor. Sadece işlettikleri komutlar aynı. Neyse cok dağıldık, en son klasorse bunlar bunları yapıyor dedik, eğer klasor değilse o zaman da sonucmuzu bir arttırıyoruz.
__________________