1. Fayl və qovluqların mövcudluğunu yoxlama metodları
Fayllarla işləmək bəzən minaalan sahədə gəzintini xatırladır: növbəti baytdan sonra sizi nə gözlədiyini heç vaxt dəqiq bilmirsiniz. Yaxşı xəbər: Java bizə “metal detektoru” verir — fayl və qovluqların mövcudluğunu yoxlamaq üçün metodlar.
File sinfi: yoxlama exists(), isFile(), isDirectory() vasitəsilə
Klassik üsul — java.io.File sinfindən istifadə etmək:
File file = new File("example.txt");
if (file.exists()) {
System.out.println("Fayl mövcuddur!");
} else {
System.out.println("Fayl tapılmadı.");
}
exists() metodu həmin adda fayl və ya qovluq varsa, true qaytarır. Amma bu hələ hamısı deyil! Bəzən nəyin mövcud olduğunu bilmək lazımdır: fayl, yoxsa qovluq.
if (file.isFile()) {
System.out.println("Bu fayldır.");
} else if (file.isDirectory()) {
System.out.println("Bu qovluqdur.");
} else {
System.out.println("Heç nə tapılmadı.");
}
Path və Files sinifləri: müasir yanaşma
Müasir proqramlarda daha yeni və güclü java.nio.file API-sindən istifadə etmək daha yaxşıdır. Burada mövcudluğu yoxlamaq üçün statik Files.exists() metodu istifadə olunur:
import java.nio.file.*;
Path path = Paths.get("example.txt");
if (Files.exists(path)) {
System.out.println("Fayl NIO vasitəsilə tapıldı!");
}
Obyektin növünü yoxlamaq üçün istifadə edin:
if (Files.isRegularFile(path)) {
System.out.println("Bu adi fayldır!");
}
if (Files.isDirectory(path)) {
System.out.println("Bu qovluqdur!");
}
Məsləhət: yeni layihələr üçün ən yaxşısı dərhal NIO (Path, Files) istifadə etməkdir, çünki bu API daha müasirdir, daha çox funksiyanı dəstəkləyir və try-with-resources ilə uyğundur.
Cədvəl: yanaşmaların müqayisəsi
| Yanaşma | Mövcudluğun yoxlanması | Növün yoxlanması (fayl/qovluq) | Müasirlik |
|---|---|---|---|
|
Bəli | Bəli (isFile(), isDirectory()) | Köhnə |
|
Bəli | Bəli (isRegularFile(), isDirectory()) | Tövsiyə olunur |
2. TOCTOU problemi: niyə yoxlama — panaseya deyil
Problem nədən ibarətdir?
Tutaq ki, siz yoxladınız: “Fayl mövcuddur!” — və dərhal onu oxumağa qərar verdiniz. Amma bu iki əməl arasında prosessor üçün əslində “əәbədiyyət” keçə bilər. Bu müddətdə fayl silinə, köçürülə, başqa proses tərəfindən əvəz edilə bilər və ya giriş icazələri dəyişdirilə bilər.
Bu, soyuducuya baxıb orada tortun olduğunu qeyd etməyə, qapını bağlayıb sonra yenidən açanda tortun artıq yeyildiyini görməyə bənzəyir. Proqramlaşdırmada da belə “ev sakinləri” var: digər proseslər, istifadəçilər, antiviruslar, fayl sisteminin özünün davranışı.
Bu niyə vacibdir?
Nəticədə, faylın mövcudluğunu yoxlasanız belə, onu açmağa cəhd edəndə yenə də istisna yarana bilər — məsələn, FileNotFoundException və ya AccessDeniedException.
Deməli, yoxlama zəmanət deyil, yalnız əlavə sığortadır. Həmişə istisnalara hazır olun və onları emal edin!
3. Təcrübə: oxumadan əvvəl faylın mövcudluğunu yoxlamaq
Mövcuddursa faylın məzmununu göstərən, yoxdursa istifadəçiyə xəbər verən funksiya əlavə edək. İki variant göstərəcəyik: köhnə və yeni API ilə.
Variant 1: File vasitəsilə
import java.io.*;
public class FileExistenceCheck {
public static void main(String[] args) {
File file = new File("notes.txt");
if (file.exists() && file.isFile()) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Faylı oxuyarkən xəta: " + e.getMessage());
}
} else {
System.out.println("Fayl 'notes.txt' tapılmadı.");
}
}
}
Variant 2: Path və Files vasitəsilə
import java.nio.file.*;
import java.io.IOException;
public class PathExistenceCheck {
public static void main(String[] args) {
Path path = Paths.get("notes.txt");
if (Files.exists(path) && Files.isRegularFile(path)) {
try {
Files.lines(path).forEach(System.out::println);
} catch (IOException e) {
System.out.println("Faylı oxuyarkən xəta: " + e.getMessage());
}
} else {
System.out.println("Fayl 'notes.txt' tapılmadı.");
}
}
}
Yoxlamadan sonra belə — istisnaları tuturuq!
Hər iki nümunədə, ilkin yoxlamaya baxmayaraq, yenə də try–catch bloklarından istifadə edirik, çünki fayl istənilən an yox ola və ya əlçatmaz ola bilər. Bu — fayllarla işin qızıl qaydasıdır!
4. Qovluğun mövcudluğunun yoxlanması
Eyni qaydada qovluğun mövcudluğunu yoxlamaq, yoxdursa — onu yaratmaq olar:
import java.nio.file.*;
public class DirectoryCheck {
public static void main(String[] args) {
Path dir = Paths.get("data");
if (Files.exists(dir) && Files.isDirectory(dir)) {
System.out.println("Qovluq 'data' tapıldı.");
} else {
System.out.println("Qovluq 'data' tapılmadı. Yaradırıq...");
try {
Files.createDirectory(dir);
System.out.println("Qovluq yaradıldı!");
} catch (IOException e) {
System.out.println("Qovluq yaradılarkən xəta: " + e.getMessage());
}
}
}
}
Yeri gəlmişkən:
Files.createDirectory() metodu qovluq artıq mövcud olanda istisna atır. Əgər qovluqlar zəncirini yaratmaq istəyirsinizsə (məsələn, "data/2025/09"), artıq mövcud olan hissələr olduqda etiraz etməyən Files.createDirectories() istifadə edin.
5. Xüsusiyyətlər və incəliklər: nisbi və mütləq yollar
Nisbi yollar
Siz "notes.txt" yazanda, proqram faylı “cari işçi qovluğunda” axtarır. Onun harada olması tətbiqi necə və haradan işə salmağınızdan asılıdır (IDE, terminal, JAR-a iki dəfə klik və s.).
Mütləq yollar
Harada axtarmağa əmin olmaq üçün mütləq yolları istifadə etmək və ya onları dinamik qurmaq daha yaxşıdır:
String userHome = System.getProperty("user.home");
Path filePath = Paths.get(userHome, "myapp", "notes.txt");
Obyektin növünün yoxlanması
Bəzən “fayl” gözlənilmədən qovluq çıxır. Ona görə təkcə mövcudluğu yox, həm də növü yoxlayın:
if (Files.isRegularFile(path)) {
// Bu məhz fayldır!
}
if (Files.isDirectory(path)) {
// Bu qovluqdur!
}
6. TOCTOU probleminin praktik nümayişi
Elə bir vəziyyəti modelləşdirək ki, fayl yoxlamadan sonra, amma açılmadan əvvəl yoxa çıxsın. Kodu işə salın və yoxlama ilə oxuma arasında faylı əl ilə silin:
import java.io.*;
import java.nio.file.*;
public class TOCTOUExample {
public static void main(String[] args) {
Path path = Paths.get("notes.txt");
if (Files.exists(path)) {
System.out.println("Fayl tapıldı, indi oxuyacağıq...");
// Bu yerdə fayl menecerinə keçin və "notes.txt" faylını əl ilə silin!
try {
Files.lines(path).forEach(System.out::println);
} catch (IOException e) {
System.out.println("Vay! Fayl yox oldu: " + e.getMessage());
}
} else {
System.out.println("Fayl tapılmadı.");
}
}
}
Nəticə:
Əgər siz faylı yoxlama və oxuma arasında silməyə macal tapsanız, istisna alacaqsınız. Bu, hətta səliqəli yoxlamanın belə gözlənilməz dəyişikliklərdən qorumadığını aydın göstərir.
7. Fayl və qovluqların mövcudluğunu yoxlayarkən tipik səhvlər
Xəta № 1: Yalnız yoxlamaya güvənmək, try-catch istifadə etməmək. Guya “fayl var”, deməli, rahatlıqla oxumaq olar — deyə düşünən başlanğıc səviyyəli proqramçılar olur. Amma fayl yoxa çıxa və ya əlçatmaz ola bilər və proqram “çökmüş” vəziyyətə düşər.
Xəta № 2: Yalnız mövcudluğu yoxlamaq, növü yoxlamamaq. Yalnız exists() yoxlanılırsa və bunun fayl yaxud qovluq olduğu dəqiqləşdirilmirsə, qovluğu fayl kimi açmağa cəhd edilə və səhv alına bilər.
Xəta № 3: İşçi qovluğu anlamadan nisbi yolları istifadə etmək. Proqram faylı “haradasa başqa yerdə” axtarır və istifadəçi nəyin səhv getdiyini anlamır.
Xəta № 4: Giriş icazələrini nəzərə almamaq. Fayl və ya qovluq mövcud ola bilər, amma oxuma/yazma hüquqları yoxdur. Belə səhvlər yalnız faylı açmağa cəhd ediləndə üzə çıxır — həmişə try–catch istifadə edin.
Xəta № 5: Müxtəlif OS-lərdə fayl adında hərf böyüklüyünü nəzərə almamaq. Windows-da fayl adları registrə həssas deyil, Linux-da isə həssasdır. Proqram "Notes.txt" faylını tapmaya bilər, əgər "notes.txt" axtarırsa.
GO TO FULL VERSION