1. Java fayllarla işləməyi necə öyrəndi
Java və fayllar: hər şey necə başladı
Bir vaxtlar, uzaq 1996-cı ildə, dilin yaradıcıları fayllarla işləməyin ilk yolunu təklif etdilər — java.io paketi. Orada File, FileInputStream, FileOutputStream, Reader, Writer və digər siniflər yarandı. Bu siniflər fayllarla müxtəlif əməliyyatlar aparmağa imkan verirdi: faylın mövcud olub-olmadığını, onun ölçüsünü, dəyişdirilmə tarixini öyrənmək və kataloqlarla işləmək.
Amma, adətən ilk versiyalarda olduğu kimi, hər şey ideal deyildi — bir çox şeyi daha rahat və təhlükəsiz etmək mümkün idi.
Köhnə API-nin məhdudiyyətləri (java.io)
- File — fayl deyil, “qısayol”. File sinfi məzmunu oxuya və ya yaza bilmir. O, yolu və metadatanı təsvir edir. Oxuma/yazma üçün ayrıca axınlar lazımdır: FileInputStream/FileOutputStream və ya Reader/Writer.
- Yollarla işləmək — əziyyətdir. "C:\\Users\\" + user + "\\Documents" kimi yolları əl ilə “yapışdırmaq” Windows və Linux arasında köçürərkən tez-tez pozulurdu.
- Simvolik linklər üçün dəstək yoxdur. Köhnə API symlink-ləri başa düşmürdü və onlarla düzgün işləməyə bilərdi.
- Atributlara zəif dəstək. Giriş hüquqları, sahibi, “gizli” kimi flaqları almaq çətin idi.
- Böyük fayllar üçün qeyri-səmərəli. Klassik axınlar böyük həcmli məlumatlar üçün rahat və sürətli ssenarilər təqdim etmirdi, asinxron giriş-çıxış yox idi.
java.nio.file-in (NIO.2, Java 7) yaranması
Java 7-də yeni paket yarandı: java.nio.file (tez-tez — NIO.2). O, bunları gətirdi:
- Path — yolun müasir abstraksiyası (ZIP daxilindəki yollar, bulud və şəbəkə fayl sistemləri daxil olmaqla).
- Files — oxuma, yazma, kopyalama, silmə üçün statik utilitlər.
- FileSystem — yalnız lokal disk ilə deyil, digər fayl sistemləri ilə də iş.
- Simvolik linklər, genişləndirilmiş atributlar, giriş hüquqları üçün dəstək.
- Asinxron giriş-çıxış və böyük verilənlər üçün yaxşılaşdırılmış performans.
- Kataloqlarla və axın API-ləri ilə rahat iş.
NIO “New Input/Output” kimi açılır və artıq on ildən çox yaşı olsa da, Java üçün bu, hələ də müasir standartdır.
2. Yanaşmaların müqayisəsi: java.io vs java.nio.file
File sinfi (java.io)
- Faylın və ya kataloqun yolunu və onların metadatasını təmsil edir.
- Faylın məzmununu oxuya/yaza bilmir.
- Mövcudluğu, ölçünü, tipini (fayl/kataloq), mütləq yolu və s. öyrənməyə imkan verir.
import java.io.File;
public class ExampleIO {
public static void main(String[] args) {
File file = new File("example.txt");
if (file.exists()) {
System.out.println("Fayl mövcuddur!");
System.out.println("Ölçü: " + file.length() + " bayt");
}
}
}
Path sinfi (java.nio.file)
- Müasir yol abstraksiyası, təbii birləşmə və normallaşdırma bacarığına malikdir.
- Yerli, arxiv və şəbəkə yollarını təmsil edə bilir.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ExampleNIOPath {
public static void main(String[] args) throws Exception {
Path path = Paths.get("example.txt");
if (Files.exists(path)) {
System.out.println("Fayl tapıldı!");
System.out.println("Ölçü: " + Files.size(path) + " bayt");
}
}
}
Files sinfi (java.nio.file)
- Tam və ya hissə-hissə oxuma/yazma üçün statik metodlar toplusu.
- Faylların kopyalanması, silinməsi, köçürülməsi.
- Kataloqların yaradılması/silinməsi.
- Genişləndirilmiş atributlara çıxış.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class ExampleNIOFiles {
public static void main(String[] args) throws Exception {
Path path = Paths.get("example.txt");
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
System.out.println(line);
}
}
}
Müqayisə cədvəli
| Funksiya | |
|
|---|---|---|
| Yolun təqdimatı | Bəli | Bəli |
| Məzmunun oxunması/yazılması | Xeyr | Bəli (Files vasitəsilə) |
| Yollarla işləmək | Rahat deyil | Rahat (resolve, normalize) |
| Simvolik linklər | Xeyr | Bəli |
| Fayl atributları | Məhduddur | Genişləndirilmiş |
| Asinxron I/O | Xeyr | Bəli (NIO.2) |
| Kross-platforma uyğunluğu | Qismən | Əla |
3. Nəyi nə vaxt istifadə etməli?
Köhnə API (java.io): nə vaxt lazımdır?
- Legacy kodu dəstəkləmək üçün. Layihə Java 7-dən əvvəl başlayıbsa və hər yerdə File, FileInputStream, FileOutputStream istifadə olunursa, uyğunluğu qorumaq lazım gələ bilər.
- Yeni layihələrdə — tövsiyə edilmir. Bu gün “köhnə” File-dan istifadə etmək VHS kasetdən video izləmək kimidir.
Yeni API (java.nio.file): müasir standart
- Yeni layihələrdə həmişə Path və Files-ə üstünlük verin.
- Daha sadə, daha təhlükəsiz, daha güclüdür və stream-lər, lambda-lar və try-with-resources ilə daha yaxşı inteqrasiya olunur.
Qısa bələdçi
- Oxuma, yazma, kopyalama, silmə? — Files vasitəsilə.
- Yollarla iş (birləşdirmə, normallaşdırma)? — Path vasitəsilə.
- Ölçü, tarix, giriş hüquqları? — Files.getAttribute() və əlaqəli metodlar.
- Kataloqların gəzilməsi, rekursiv? — Files.walk, Files.list.
4. Nümunələr: köhnə və yeni API-də kod necə görünərdi
Nümunə 1: Faylın mövcudluğunu yoxlamaq
Köhnə üsul:
import java.io.File;
File file = new File("data.txt");
if (file.exists()) {
System.out.println("Fayl tapıldı!");
}
Yeni üsul:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("data.txt");
if (Files.exists(path)) {
System.out.println("Fayl tapıldı!");
}
Nümunə 2: Fayldakı bütün sətrlərin oxunması
Köhnə üsul:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
File file = new File("data.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
Yeni üsul:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
Path path = Paths.get("data.txt");
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
System.out.println(line);
}
Şərh: Yeni üsul daha qısa və daha təhlükəsizdir; try-with-resources ilə resursların idarə olunması daha da asandır.
Nümunə 3: Sətrin fayla yazılması
Köhnə üsul:
import java.io.FileWriter;
FileWriter writer = new FileWriter("output.txt");
writer.write("Salam, fayl!");
writer.close();
Yeni üsul:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("output.txt");
Files.write(path, "Salam, fayl!".getBytes());
5. Faydalı incəliklər
Niyə Java hər şeyi yenidən qurdu?
- Təhlükəsizlik və etibarlılıq. Resursların bağlanması və yollarla bağlı daha az səhv.
- Kross-platforma. Windows, Linux və hətta ZIP arxivləri üçün vahid siniflər.
- Asan genişlənmə. Bulud və şəbəkə fayl sistemlərinə dəstək əlavə etmək daha rahatdır.
- Performans. Böyük fayllarda daha yaxşı davranış və asinxron əməliyyatlar.
- Müasir Java stack-i ilə uyğunluq. Lambda-lar, stream-lər, try-with-resources.
Köhnə API-dən yenisinə necə keçmək olar?
Demək olar ki, həmişə File-ı Path-ə və əksinə çevirmək mümkündür:
File file = new File("data.txt");
Path path = file.toPath();
File file2 = path.toFile();
Köhnə kodla qarşılaşsanız nə etməli?
- Qorxmayın: hər şeyi daha sadə və müasir etmək olar.
- İmkan varsa — java.nio.file-ə köçürün.
- İmkan yoxdursa — körpülərdən (toPath(), toFile()) istifadə edin və tədricən miqrasiya edin.
6. Son nümunə: mini-tətbiq
Nümunə: Faylın mövcud olub-olmadığını yoxlayırıq və onun ölçüsünü çıxarırıq.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileInfo {
public static void main(String[] args) {
Path path = Paths.get("test.txt");
if (Files.exists(path)) {
try {
long size = Files.size(path);
System.out.println("Fayl tapıldı. Ölçü: " + size + " bayt");
} catch (Exception e) {
System.out.println("Faylın ölçüsünü əldə edərkən xəta: " + e.getMessage());
}
} else {
System.out.println("Fayl tapılmadı!");
}
}
}
Burada nələri işlətdik:
- Path — yolun təqdimatı.
- Files.exists() — mövcudluğun yoxlanması.
- Files.size() — ölçünün alınması.
7. Fayl API-ləri ilə işləyərkən tipik səhvlər
Səhv №1: File-ın məzmunu oxuya və ya yaza biləcəyini zənn etmək. Əslində File yalnız “qısayol”dur. Oxuma/yazma üçün FileInputStream/FileOutputStream (köhnə API) və ya Files (yeni API) utilitlərindən istifadə edin.
Səhv №2: Yolları + və ya slash ilə əl ilə birləşdirmək. Bu, müxtəlif OS-lərdə səhvlərə səbəb olur. Path.resolve() və ya bir neçə arqumentlə Paths.get(...) istifadə edin.
Səhv №3: Axını bağlamağı unutmaq. Köhnə API-də bu, resurs sızmalarının tez-tez səbəbidir. Yeni API-də Files vasitəsilə bir çox əməliyyat axın yaratmır, lazım olan yerlərdə isə try-with-resources tətbiq edin.
Səhv №4: Yeni layihələrdə köhnə API-dən istifadə. Yeni layihəyə başlayırsınızsa — java.nio.file seçin. java.io-ya yalnız legacy kodla uyğunluq üçün müraciət etmək məntiqlidir.
GO TO FULL VERSION