mannaxxx 1
mannaxxx
Agora Metin2 1
Agora Metin2
[DEV]AB 1
[DEV]AB
Sevdamsın 1
Sevdamsın
TuZaKK 1
TuZaKK
kaptanmikro1 1
kaptanmikro1
farkmt2official 2
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] Recursive Klasor Olusturma ve Silme

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Recursive Klasor Olusturma ve Silme​


Selam arkadaslar, bugun Node.js'te ic ice klasor yapilari olusturma ve silme islemlerini konusacagiz. Bu basit bir konu gibi gorunebilir ama inanin bana, ozellikle cross-platform uyumluluk ve hata yonetimi acisindan dikkat edilmesi gereken bir cok ince nokta var. Ben gecmis projelerimde bu konuda epey bocaladim, simdi ogrendiklerimi sizinle paylasacagim.

Recursive Klasor Olusturma​


Klasik bir senaryo dusunelim: uploads/2024/07/thumbnails gibi bir klasor yapisi olusturmak istiyorsunuz. Eger sadece fs.mkdir ile en son klasoru olusturmaya calisirsiniz, aradaki klasorler yoksa hata alirsiniz. Iste bu noktada recursive secenegi devreye giriyor. Node.js 10.12.0 ile birlikte mkdir fonksiyonuna recursive secenegi eklendi ve artik aradaki tum klasorleri otomatik olarak olusturabiliyoruz.

Benim tavsiyem, klasor olusturma islemlerinde her zaman recursive: true kullanmaniz. Klasor zaten varsa hata vermez, yoksa tum ara klasorlerle birlikte olusturur. Bu sayede gereksiz kontroller yapmak zorunda kalmazsiniz. Ha bu arada, eskiden bu isi yapmak icin mkdirp gibi ucuncu parti kutuphaneler kullanilirdi ama artik buna gerek yok.

JavaScript:
const fs = require('fs/promises');
const path = require('path');

// Basit recursive klasor olusturma
async function klasorOlustur() {
    const klasorYolu = path.join(__dirname, 'uploads', '2024', '07', 'thumbnails');

    try {
        // recursive: true ile aradaki tum klasorler otomatik olusur
        await fs.mkdir(klasorYolu, { recursive: true });
        console.log('Klasor yapisi olusturuldu:', klasorYolu);
    } catch (error) {
        console.error('Klasor olusturma hatasi:', error.message);
    }
}

// Proje yapisini otomatik olusturma
async function projeYapisiOlustur(projeAdi) {
    const temelYol = path.join(__dirname, projeAdi);

    const klasorler = [
        'src/controllers',
        'src/models',
        'src/routes',
        'src/middlewares',
        'src/utils',
        'src/config',
        'public/css',
        'public/js',
        'public/images',
        'views/partials',
        'tests/unit',
        'tests/integration',
        'logs',
        'temp'
    ];

    console.log(`"${projeAdi}" proje yapisi olusturuluyor...\n`);

    for (const klasor of klasorler) {
        const tamYol = path.join(temelYol, klasor);
        await fs.mkdir(tamYol, { recursive: true });
        console.log(`  Olusturuldu: ${klasor}/`);
    }

    // Bos .gitkeep dosyalari ekle
    for (const klasor of klasorler) {
        const gitkeep = path.join(temelYol, klasor, '.gitkeep');
        await fs.writeFile(gitkeep, '');
    }

    console.log('\nProje yapisi basariyla olusturuldu!');
}

// Calistir
async function main() {
    await klasorOlustur();
    await projeYapisiOlustur('yeni-proje');
}

main().catch(console.error);

Recursive Klasor Silme​


Klasor silme islemi biraz daha dikkatli olunmasi gereken bir konu. Ici dolu bir klasoru silmek icin once icerigini bosaltmaniz gerekir. Node.js 14.14.0 ile birlikte fs.rm fonksiyonu eklendi ve recursive silme islemi cok kolaylasti. Oncesinde bu isi yapmak icin ya ucuncu parti kutuphane kullanmaniz ya da kendi recursive silme fonksiyonunuzu yazmaniz gerekiyordu.

Dikkat edilmesi gereken bir nokta: rmdir deprecated oldu, onun yerine rm kullanin. Ayrica recursive silme islemini calistirmadan once silmek istediginiz yolun dogru oldugundan emin olun. Yanlis bir yol verirseniz onemli dosyalarinizi kaybedebilirsiniz. Ben bunu aci tecrubemle ogrendim, bir kere yanlislikla node_modules yerine src klasorunu silmistim. Git sayesinde kurtardim ama o an kalp krizi geciriyordum resmen.

JavaScript:
const fs = require('fs/promises');
const fsSenkron = require('fs');
const path = require('path');

// Guvenli recursive silme
async function guvenliSil(hedefYol) {
    // Guvenlik kontrolleri
    const mutlakYol = path.resolve(hedefYol);
    const evKlasoru = require('os').homedir();

    // Ev klasorunu veya kok dizini silmeye calisma
    if (mutlakYol === evKlasoru || mutlakYol === '/' || mutlakYol === 'C:\\') {
        throw new Error('Kritik dizin silinemez: ' + mutlakYol);
    }

    // Hedef var mi kontrol et
    try {
        const stat = await fs.stat(mutlakYol);
        if (!stat.isDirectory()) {
            throw new Error('Hedef bir klasor degil: ' + mutlakYol);
        }
    } catch (error) {
        if (error.code === 'ENOENT') {
            console.log('Klasor zaten mevcut degil:', mutlakYol);
            return;
        }
        throw error;
    }

    // Icerik sayisini goster
    const icerik = await klasorIceriginiSay(mutlakYol);
    console.log(`Silinecek: ${icerik.dosyaSayisi} dosya, ${icerik.klasorSayisi} klasor`);

    // Silme islemi
    await fs.rm(mutlakYol, {
        recursive: true,
        force: true,       // Hatalari yoksay
        maxRetries: 3,     // Windows'ta dosya kilidi sorunu icin
        retryDelay: 100    // Denemeler arasi bekleme
    });

    console.log('Basariyla silindi:', mutlakYol);
}

// Klasor icerigini recursive olarak say
async function klasorIceriginiSay(klasorYolu) {
    let dosyaSayisi = 0;
    let klasorSayisi = 0;

    async function say(yol) {
        const elemanlar = await fs.readdir(yol, { withFileTypes: true });

        for (const eleman of elemanlar) {
            const tamYol = path.join(yol, eleman.name);

            if (eleman.isDirectory()) {
                klasorSayisi++;
                await say(tamYol);
            } else {
                dosyaSayisi++;
            }
        }
    }

    await say(klasorYolu);
    return { dosyaSayisi, klasorSayisi };
}

// Gecici dosyalari temizleme fonksiyonu
async function geciciDosyalariTemizle(klasorYolu, maxYasGun = 7) {
    const simdi = Date.now();
    const maxYasMs = maxYasGun * 24 * 60 * 60 * 1000;
    let silinenSayisi = 0;

    try {
        const elemanlar = await fs.readdir(klasorYolu, { withFileTypes: true });

        for (const eleman of elemanlar) {
            const tamYol = path.join(klasorYolu, eleman.name);
            const stat = await fs.stat(tamYol);
            const yas = simdi - stat.mtimeMs;

            if (yas > maxYasMs) {
                if (eleman.isDirectory()) {
                    await fs.rm(tamYol, { recursive: true, force: true });
                } else {
                    await fs.unlink(tamYol);
                }
                silinenSayisi++;
                console.log(`  Silindi: ${eleman.name} (${Math.floor(yas / 86400000)} gun eski)`);
            }
        }

        console.log(`Toplam ${silinenSayisi} eleman silindi.`);
    } catch (error) {
        console.error('Temizleme hatasi:', error.message);
    }
}

// Kullanim
async function main() {
    // Ornek: gecici klasoru temizle
    const tempKlasor = path.join(__dirname, 'temp');
    await fs.mkdir(tempKlasor, { recursive: true });

    // Ornek dosyalar olustur
    for (let i = 0; i < 5; i++) {
        await fs.writeFile(
            path.join(tempKlasor, `temp_${i}.txt`),
            'gecici veri'
        );
    }

    // 0 gunluk limit ile hepsini sil
    await geciciDosyalariTemizle(tempKlasor, 0);
}

main().catch(console.error);

Pratik Ipuclari​


Node.js'te klasor islemleri yaparken su noktalara dikkat edin. Her zaman path.join veya path.resolve kullanin, string birlestirme ile yol olusturmayin. Windows ve Linux'ta yol ayiraclari farklidir ve path modulu bu farki sizin icin halleder. Silme islemlerinden once mutlaka kontrol yapin. recursive: true kullanirken dikkatli olun cunku geri donusu yoktur. Buyuk klasor yapilari olustururken Promise.all ile paralel olusturma yapabilirsiniz ama cok fazla acik dosya tanimlayicisi sorunu yasamamak icin batch'ler halinde yapin.

Son olarak, production ortaminda klasor islemleri yaparken loglama yapmayi ihmal etmeyin. Hangi klasorlerin ne zaman olusturuldugu veya silindigi bilgisi, sorun cikardiginda hayat kurtarici olabilir. Neyse, bu kadarlik bu konu. Gorusmek uzere!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst