Ön Hazırlık ve Gereksinimler
Node.js ile dosya işlemleri yapmaya başlamadan önce bilgisayarınızda güncel bir Node.js sürümünün yüklü olması gerekir. 2026 itibarıyla, LTS (Long Term Support) sürümlerini kullanmanız önerilir. Kurulumun doğruluğunu kontrol etmek için terminalinize node -v komutunu yazarak sürüm bilgisini görebilirsiniz.
Projenizi başlatmak için bir klasör oluşturun ve terminalde bu klasörün içine girerek npm init -y komutunu çalıştırın. Bu işlem, projenizin kök dizininde bir package.json dosyası oluşturacaktır. Dosya sistemi işlemleri için herhangi bir dış kütüphane kurmanıza gerek yoktur; çünkü fs modülü Node.js çekirdeği ile birlikte gelir.
Dosya Okuma İşlemi: fs.readFile Kullanımı
Dosya okuma, bir metin dosyasının içeriğini belleğe almak için kullanılır. Node.js'de bu işlem için en temel yöntem fs.readFile fonksiyonudur. Bu fonksiyon, dosya yolunu ve bir geri çağırma (callback) fonksiyonunu parametre olarak alır.
const fs = require('fs');
fs.readFile('ornek.txt', 'utf8', (hata, veri) => {
if (hata) {
console.error('Dosya okunamadı:', hata);
return;
}
console.log('Dosya İçeriği:', veri);
});
Yukarıdaki kodda 'utf8' parametresi, dosyanın ham buffer verisi yerine okunabilir bir metin dizisi olarak dönmesini sağlar. Eğer bu parametreyi belirtmezseniz, çıktı olarak Buffer nesnesi alırsınız.
Modern Yaklaşım: fs/promises Kullanımı
Modern Node.js uygulamalarında callback yapısı yerine async/await sözdizimi tercih edilir. Bu yöntem, kodun okunabilirliğini artırır ve "callback hell" denilen karmaşık iç içe geçmiş fonksiyon yapılarından kaçınmanızı sağlar. fs/promises modülü, dosya işlemlerini Promise tabanlı hale getirir.
const fs = require('fs/promises');
async function dosyaOku() {
try {
const veri = await fs.readFile('ornek.txt', 'utf8');
console.log('Okunan İçerik:', veri);
} catch (hata) {
console.error('Hata oluştu:', hata.message);
}
}
dosyaOku();
Bu yaklaşım, hata yönetimi için try/catch bloklarını kullanmanıza olanak tanır. Uygulama geliştirirken asenkron yapıları tercih etmek, dosya okuma işlemi sırasında uygulamanızın diğer işlemlerini engellememesini (non-blocking I/O) sağlar.
Dosya Yazma İşlemi: fs.writeFile
Dosya yazma işlemi, mevcut bir dosyayı üzerine yazmak veya yeni bir dosya oluşturmak için kullanılır. fs.writeFile fonksiyonu, belirttiğiniz dosya yoluna veriyi yazar. Eğer dosya zaten varsa, içeriği tamamen silinir ve yeni veri yazılır.
const fs = require('fs/promises');
async function dosyaYaz() {
const icerik = 'Bu metin Node.js ile dosyaya yazılmıştır.';
try {
await fs.writeFile('kayit.txt', icerik, 'utf8');
console.log('Dosya başarıyla yazıldı.');
} catch (hata) {
console.error('Yazma hatası:', hata);
}
}
dosyaYaz();
Dosya yazma işlemlerinde, verinin yazılacağı dizinin varlığından emin olmalısınız. Aksi takdirde, Node.js "ENOENT" (Error No Entity) hatası döndürecektir.
Dosyaya Veri Ekleme: appendFile
Bazen dosyanın mevcut içeriğini silmeden sonuna yeni veri eklemek istersiniz. Bu durumda appendFile fonksiyonu kullanılır. Log tutma veya kullanıcı geçmişi kaydetme gibi senaryolarda oldukça kullanışlıdır.
const fs = require('fs/promises');
async function veriEkle() {
const yeniSatir = '\nYeni bir satır eklendi.';
try {
await fs.appendFile('kayit.txt', yeniSatir, 'utf8');
console.log('Veri başarıyla eklendi.');
} catch (hata) {
console.error('Ekleme hatası:', hata);
}
}
veriEkle();
Güvenlik Uyarısı: Kullanıcıdan gelen verileri doğrudan dosya yollarına veya dosya içeriğine yazarken dikkatli olun. "Path Traversal" (yol geçişi) saldırılarına karşı kullanıcı girdilerini her zaman temizleyin (sanitize) ve dosya yollarını
path.join()ile oluşturun.
Dosya Sistemi Metotlarının Karşılaştırılması
Node.js dosya sistemi işlemleri için farklı yaklaşımlar sunar. İhtiyacınıza göre en uygun yöntemi seçmek performans açısından kritiktir.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| fs.readFileSync | Basit, senkron | Uygulamayı dondurur (blocking) |
| fs.readFile (Callback) | Asenkron, eski | Callback hell riski |
| fs/promises | Modern, temiz | Eski Node sürümlerinde kısıtlı |
Dosya Varlığını Kontrol Etme ve Silme
Bir işlem yapmadan önce dosyanın var olup olmadığını kontrol etmek veya artık ihtiyaç duyulmayan dosyaları silmek, dosya sistemi yönetiminin bir parçasıdır. fs.stat veya fs.unlink metotları bu iş için kullanılır.
const fs = require('fs/promises');
async function dosyaYonetimi() {
try {
// Dosya var mı kontrol et
await fs.access('kayit.txt');
console.log('Dosya mevcut, siliniyor...');
// Dosyayı sil
await fs.unlink('kayit.txt');
console.log('Dosya silindi.');
} catch (hata) {
console.log('Dosya bulunamadı veya silinemedi.');
}
}
dosyaYonetimi();
Sorumluluk Reddi: Bu rehberde paylaşılan kodlar eğitim amaçlıdır. Üretim ortamında (production) dosya işlemleri yaparken hata yakalama mekanizmalarını (try/catch) ve dosya izinlerini (permissions) mutlaka yapılandırın. Kritik verilerin güvenliği için dosya şifreleme yöntemlerini araştırmanız önerilir.
Sıkça Sorulan Sorular
Senkron ve Asenkron dosya okuma arasındaki fark nedir?
Senkron (sync) yöntemler, dosya işlemi bitene kadar Node.js'in ana iş parçacığını (main thread) durdurur. Asenkron (async) yöntemler ise işlem arka planda sürerken programın çalışmaya devam etmesine izin verir; bu nedenle sunucu taraflı uygulamalarda mutlaka asenkron yöntemler tercih edilmelidir.
Dosya okurken "Buffer" hatası alıyorum, neden?
Eğer fs.readFile fonksiyonunda 'utf8' gibi bir kodlama belirtmezseniz, Node.js veriyi ham binary (ikili) veri olan Buffer nesnesi olarak döndürür. Okunabilir metin için mutlaka kodlama parametresi ekleyin.
Aynı anda birden fazla dosyaya yazabilir miyim?
Evet, Node.js'in asenkron yapısı sayesinde Promise.all() kullanarak birden fazla dosyaya eş zamanlı olarak yazma işlemi gerçekleştirebilirsiniz.
Dosya yollarını nasıl yönetmeliyim?
Dosya yollarını el ile birleştirmek yerine Node.js içerisindeki path modülünü kullanın. path.join(__dirname, 'dosya.txt') kullanımı, işletim sistemi farklılıklarından kaynaklanan hataları önler.
Büyük dosyaları nasıl okumalıyım?
Çok büyük dosyaları fs.readFile ile belleğe yüklemek RAM sorunlarına yol açar. Bunun yerine fs.createReadStream kullanarak dosyayı parçalar halinde (stream) okumanız gerekir.
Dosya İşlemlerinde Performans Optimizasyonu ve Buffer Yönetimi
Node.js dosya sistemi işlemlerinde yüksek performans elde etmek, özellikle yoğun trafik alan uygulamalarda kritik bir öneme sahiptir. Dosya okuma ve yazma süreçlerinde yapılan hatalar, uygulamanızın "event loop" yapısını tıkayabilir veya bellek tüketimini (memory footprint) kontrolsüz bir şekilde artırabilir.
Buffer Boyutunu Optimize Etmek
Varsayılan olarak Node.js, okuma işlemlerinde belirli bir buffer boyutu kullanır. Ancak, çok sayıda küçük dosya ile çalışıyorsanız, her işlem için yeni bir buffer oluşturmak yerine Buffer.allocUnsafe kullanarak bellek tahsisini hızlandırabilirsiniz. Ancak dikkatli olun; bu yöntem bellekteki eski verileri temizlemez, bu yüzden üzerine veri yazacağınızdan emin olmalısınız.
const fs = require('fs');
// 16KB'lık özel bir buffer ile okuma yapma
const buffer = Buffer.alloc(16384);
fs.open('veri.txt', 'r', (err, fd) => {
fs.read(fd, buffer, 0, buffer.length, 0, (err, bytesRead) => {
console.log(`${bytesRead} bayt veri okundu.`);
});
});
Stream (Akış) Kullanarak Bellek Dostu İşlemler
Dosyaları tek seferde RAM'e yüklemek yerine pipe mekanizmasını kullanmak, uygulamanızın CPU ve RAM tüketimini minimize eder. Özellikle büyük log dosyalarını işlerken veya dosya transferi yaparken bu yöntem zorunludur.
const fs = require('fs');
const readStream = fs.createReadStream('buyuk-dosya.log');
const writeStream = fs.createWriteStream('yedek-dosya.log');
// Veriyi parçalar halinde okuyup doğrudan diğerine aktarır
readStream.pipe(writeStream);
readStream.on('error', (err) => console.error('Okuma hatası:', err));
writeStream.on('finish', () => console.log('Dosya başarıyla kopyalandı.'));
Dosya Sistemi Hatalarını Yönetme ve Debugging
Dosya sistemi işlemleri, dış dünyaya (disk) bağımlı olduğu için "Permission Denied" (Erişim Reddedildi), "File Not Found" (Dosya Bulunamadı) veya "Disk Full" (Disk Dolu) gibi hatalarla karşılaşmanız kaçınılmazdır. Profesyonel bir uygulamada bu hataları merkezi bir yapıda yönetmek gerekir.
Hata Kodlarını Anlamak
Node.js, dosya sistemi hatalarında standart hata kodları döndürür. Bu kodları kontrol ederek uygulamanızın nasıl tepki vereceğini belirleyebilirsiniz:
- ENOENT: Dosya veya dizin bulunamadı.
- EACCES: Dosyaya erişim izni yok.
- EEXIST: Dosya zaten mevcut (yeni dosya oluştururken çakışma).
- EISDIR: Dosya beklenen yerde bir dizin var.
const fs = require('fs').promises;
async function guvenliDosyaOku(dosyaYolu) {
try {
const data = await fs.readFile(dosyaYolu, 'utf8');
return data;
} catch (err) {
if (err.code === 'ENOENT') {
console.error('Hata: Dosya mevcut değil, varsayılan değer döndürülüyor.');
return '';
} else if (err.code === 'EACCES') {
console.error('Hata: Dosyayı okumak için yetkiniz yok.');
throw err;
}
throw err;
}
}
Bu yaklaşım, uygulamanızın beklenmedik bir şekilde çökmesini (crash) engeller ve kullanıcıya veya log sistemine anlamlı hata mesajları dönmenize olanak tanır. Hata ayıklama sürecinde fs.promises ile async/await yapısını kullanmak, stack trace takibini çok daha kolay hale getirir.
Sonuç
Node.js ile dosya okuma ve yazma işlemleri, sunucu tarafı programlamanın temel taşlarından biridir. Bu rehberde, fs modülünün modern Promise tabanlı kullanımını, hata yönetimini ve dosya sistemi üzerindeki temel işlemleri adım adım inceledik. Artık verileri kalıcı hale getirebilir ve dış kaynaklardan gelen verileri işleyebilirsiniz.
Bir sonraki adım olarak, fs.createReadStream ve fs.createWriteStream kullanarak "Stream" (akış) yapısını öğrenmeniz, büyük veri setleriyle çalışırken uygulamanızın performansını ciddi oranda artıracaktır. Kod yazmaya devam ederek bu pratikleri pekiştirmeyi unutmayın.


Yorumlar (0)
Yorum Yaz