Ders İçeriği
Java, dosya ve dizinlerle etkileşim kurmak için zengin bir giriş/çıkış (Input/Output - I/O) API'si sunar. Bu API, dosya okuma, yazma, oluşturma, silme ve dizin işlemleri gibi çeşitli görevleri yerine getirmemizi sağlar. Bu bölümde, Java'da dosya işlemlerinin temel prensiplerini ve yaygın olarak kullanılan sınıfları inceleyeceğiz.
Temel Kavramlar: Akışlar (Streams)
Java I/O, akışlar (streams) kavramına dayanır. Akış, bir veri kaynağı ile bir veri hedefi arasındaki veri akışını temsil eder. İki ana akış türü vardır:
- Giriş Akışları (Input Streams): Veri kaynağından (örneğin bir dosya, ağ bağlantısı) veri okumak için kullanılır.
- Çıkış Akışları (Output Streams): Veri hedefine (örneğin bir dosya, ağ bağlantısı) veri yazmak için kullanılır.
Akışlar ayrıca iki kategoriye ayrılır:
- Bayt Akışları (Byte Streams): Bayt bayt veri okuma ve yazma işlemleri için kullanılır. İkili veriler (resimler, ses dosyaları vb.) için uygundur.
InputStream
veOutputStream
temel sınıflarıdır. - Karakter Akışları (Character Streams): Karakter karakter veri okuma ve yazma işlemleri için kullanılır. Metin verileri için uygundur ve karakter kodlamalarını (UTF-8, UTF-16 vb.) otomatik olarak ele alır.
Reader
veWriter
temel sınıflarıdır.
File
Sınıfı
java.io.File
sınıfı, dosya veya dizin yollarını temsil etmek ve dosya sistemi üzerinde işlemler yapmak için kullanılır. Dosyanın içeriğini okuma veya yazma yeteneği sağlamaz, sadece dosya veya dizinle ilgili meta verileri ve işlemleri (oluşturma, silme, yeniden adlandırma vb.) yönetir.
import java.io.File;
public class FileIslemleri {
public static void main(String[] args) {
// Yeni bir File nesnesi oluşturma
File dosya = new File("ornek.txt");
try {
// Dosya varsa sil, yoksa oluştur
if (dosya.exists()) {
System.out.println("Dosya zaten var. Siliniyor...");
dosya.delete();
}
if (dosya.createNewFile()) {
System.out.println("Dosya oluşturuldu: " + dosya.getName());
} else {
System.out.println("Dosya oluşturulamadı.");
}
// Dosya bilgileri
System.out.println("Dosya yolu: " + dosya.getAbsolutePath());
System.out.println("Yazılabilir mi: " + dosya.canWrite());
System.out.println("Okunabilir mi: " + dosya.canRead());
System.out.println("Boyut (bayt): " + dosya.length());
// Dizin oluşturma
File dizin = new File("yeni_dizin");
if (dizin.mkdir()) {
System.out.println("Dizin oluşturuldu: " + dizin.getName());
}
// Dizin içeriğini listeleme
File mevcutDizin = new File("."); // Mevcut dizin
String[] icerik = mevcutDizin.list();
System.out.println("Mevcut dizin içeriği:");
for (String eleman : icerik) {
System.out.println(eleman);
}
} catch (Exception e) {
System.err.println("Bir hata oluştu: " + e.getMessage());
e.printStackTrace();
}
}
}
Dosya Okuma ve Yazma
Metin Dosyaları İçin (Karakter Akışları)
FileWriter
veFileReader
: Metin dosyalarına karakter bazında yazma ve okuma için kullanılır. GenellikleBufferedWriter
veBufferedReader
ile birlikte kullanılarak performans artırılır.import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.BufferedReader; import java.io.BufferedWriter; public class MetinDosyaIslemleri { public static void main(String[] args) { String dosyaAdi = "deneme.txt"; String icerik = "Bu bir deneme metnidir.\nJava dosya işlemleri."; // Dosyaya Yazma try (BufferedWriter writer = new BufferedWriter(new FileWriter(dosyaAdi))) { writer.write(icerik); System.out.println("Dosyaya yazma başarılı."); } catch (IOException e) { System.err.println("Dosyaya yazarken hata oluştu: " + e.getMessage()); } // Dosyadan Okuma try (BufferedReader reader = new BufferedReader(new FileReader(dosyaAdi))) { String satir; System.out.println("Dosya içeriği:"); while ((satir = reader.readLine()) != null) { System.out.println(satir); } System.out.println("Dosyadan okuma başarılı."); } catch (IOException e) { System.err.println("Dosyadan okurken hata oluştu: " + e.getMessage()); } } }
Bayt Dosyaları İçin (Bayt Akışları)
FileOutputStream
veFileInputStream
: İkili verilere (bayt dizileri) yazma ve okuma için kullanılır. Resim, ses veya diğer ikili dosyalar için uygundur.import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class BaytDosyaIslemleri { public static void main(String[] args) { String kaynakDosya = "kaynak.jpg"; // Örnek bir resim dosyası String hedefDosya = "kopya.jpg"; try (FileInputStream fis = new FileInputStream(kaynakDosya); FileOutputStream fos = new FileOutputStream(hedefDosya)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } System.out.println("Dosya kopyalama başarılı."); } catch (IOException e) { System.err.println("Dosya işlemi sırasında hata oluştu: " + e.getMessage()); } } }
NIO.2
(New I/O) API
Java 7 ile birlikte tanıtılan NIO.2 API, dosya sistemi işlemleri için daha modern ve esnek bir yaklaşım sunar. java.nio.file
paketi altında yer alır ve özellikle büyük dosyalarla veya karmaşık dosya sistemi operasyonlarıyla çalışırken daha iyi performans ve daha temiz kod sağlar.
Path
Sınıfı: Dosya veya dizin yollarını temsil eder.File
sınıfına göre daha güçlü ve esnektir.Files
Sınıfı: Statik metotlar aracılığıyla dosya ve dizin işlemleri için yardımcı metotlar sunar.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.io.IOException;
public class NIO2DosyaIslemleri {
public static void main(String[] args) {
Path dosyaYolu = Paths.get("nio_ornek.txt");
// Dosyaya Yazma (tek satırda)
try {
Files.write(dosyaYolu, "NIO.2 ile yazılan ilk satır.\n".getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Files.write(dosyaYolu, "İkinci satır.".getBytes(), StandardOpenOption.APPEND);
System.out.println("NIO.2 ile dosyaya yazma başarılı.");
} catch (IOException e) {
System.err.println("NIO.2 yazma hatası: " + e.getMessage());
}
// Dosyadan Okuma (tüm satırları listeye alma)
try {
List<String> satirlar = Files.readAllLines(dosyaYolu);
System.out.println("NIO.2 ile dosya içeriği:");
for (String satir : satirlar) {
System.out.println(satir);
}
System.out.println("NIO.2 ile dosyadan okuma başarılı.");
} catch (IOException e) {
System.err.println("NIO.2 okuma hatası: " + e.getMessage());
}
// Dosya kopyalama
Path kaynak = Paths.get("nio_ornek.txt");
Path hedef = Paths.get("nio_kopya.txt");
try {
Files.copy(kaynak, hedef, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
System.out.println("NIO.2 ile dosya kopyalama başarılı.");
} catch (IOException e) {
System.err.println("NIO.2 kopyalama hatası: " + e.getMessage());
}
// Dosya silme
try {
Files.deleteIfExists(hedef);
System.out.println("NIO.2 ile dosya silme başarılı.");
} catch (IOException e) {
System.err.println("NIO.2 silme hatası: " + e.getMessage());
}
}
}
Java'da dosya işlemleri, uygulamaların dış dünya ile etkileşim kurması için temel bir yetenektir. Hangi API'yi kullanacağınız (eski I/O veya NIO.2), projenizin gereksinimlerine ve Java sürümüne bağlıdır. Genellikle, yeni projelerde NIO.2 API'sinin kullanılması önerilir. Bir sonraki derste Çoklu İş Parçacığı (Multithreading) konusunu inceleyeceğiz.