mannaxxx 1
mannaxxx
Bvural41 1
Bvural41
Agora Metin2 1
Agora Metin2
berkmenoo 1
berkmenoo
farkmt2official 1
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Hikaye Ekle

[NODE JS] fs.rename ile Dosya Taşıma

nodejs.png


[NODE JS] fs.rename ile Dosya Taşıma​


Merhaba arkadaşlar. fs.rename fonksiyonu dosya taşıma ve yeniden adlandırma işlemleri için kullanılır. Basit görünse de bazı sürprizleri var. Özellikle farklı disk bölümleri arasında taşıma yapamama sorunu production'da sıkça karşılaşılan bir durum. Bugün rename'in nasıl çalıştığını ve alternatif çözümleri göstereceğim.

rename ile Taşıma ve Yeniden Adlandırma​


fs.rename iki temel işlem yapar: dosyayı yeniden adlandırma ve aynı dosya sistemi içinde taşıma. Dikkat edin, aynı dosya sistemi dedim. Eğer kaynak ve hedef farklı disk bölümlerindeyse veya farklı mount point'lerdeyse rename hata verir (EXDEV). Bu durumda kopyala-sil stratejisi kullanmanız gerekir.

Ben rename'i en çok upload edilen dosyaları geçici klasörden kalıcı klasöre taşımak için kullanıyorum. Ayrıca atomik dosya yazımlarında da kullanışlı: geçici dosyaya yaz, sonra rename ile orijinal dosyanın yerine koy. Bu sayede yarım kalmış yazma işlemi sorunlarından kaçınırsınız.

JavaScript:
// === fs.rename ile DOSYA TAŞIMA ===

const fs = require('fs');
const path = require('path');

const testDir = __dirname;

// Test dosyaları oluştur
const kaynak = path.join(testDir, 'kaynak-dosya.txt');
fs.writeFileSync(kaynak, 'Bu dosya taşınacak.', 'utf-8');

// 1. Senkron yeniden adlandırma
console.log('=== Senkron Rename ===');
try {
    const yeniAd = path.join(testDir, 'yeni-ad-dosya.txt');
    fs.renameSync(kaynak, yeniAd);
    console.log(`${path.basename(kaynak)} -> ${path.basename(yeniAd)}`);

    // Geri adlandır
    fs.renameSync(yeniAd, kaynak);
} catch (hata) {
    console.error('Rename hatası:', hata.message);
}

// 2. Asenkron rename - Promise
async function dosyaTasi(kaynakYol, hedefYol) {
    try {
        // Hedef dizinin var olduğundan emin ol
        const hedefDizin = path.dirname(hedefYol);
        await fs.promises.mkdir(hedefDizin, { recursive: true });

        await fs.promises.rename(kaynakYol, hedefYol);
        console.log(`Taşındı: ${path.basename(kaynakYol)} -> ${hedefYol}`);
        return true;
    } catch (hata) {
        if (hata.code === 'EXDEV') {
            // Farklı dosya sistemi - kopyala ve sil
            console.log('Farklı dosya sistemi, kopyala-sil yapılıyor...');
            await fs.promises.copyFile(kaynakYol, hedefYol);
            await fs.promises.unlink(kaynakYol);
            console.log('Kopyala-sil ile taşındı');
            return true;
        }
        console.error('Taşıma hatası:', hata.message);
        return false;
    }
}

// 3. Toplu yeniden adlandırma
async function topluYenidenAdlandir(dizin, donusturFn) {
    const dosyalar = await fs.promises.readdir(dizin);
    let sayac = 0;

    for (const dosya of dosyalar) {
        const yeniAd = donusturFn(dosya);
        if (yeniAd && yeniAd !== dosya) {
            const eskiYol = path.join(dizin, dosya);
            const yeniYol = path.join(dizin, yeniAd);

            // Sadece dosyaları adlandır (klasörleri atla)
            const stat = await fs.promises.stat(eskiYol);
            if (stat.isFile()) {
                await fs.promises.rename(eskiYol, yeniYol);
                console.log(`  ${dosya} -> ${yeniAd}`);
                sayac++;
            }
        }
    }

    return sayac;
}

// 4. Upload dosyası taşıma senaryosu
async function uploadIsle(geciciYol, orijinalAd) {
    const uzanti = path.extname(orijinalAd);
    const benzersizAd = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}${uzanti}`;
    const kaliciDizin = path.join(testDir, 'uploads');

    try {
        await fs.promises.mkdir(kaliciDizin, { recursive: true });
        const hedefYol = path.join(kaliciDizin, benzersizAd);
        await fs.promises.rename(geciciYol, hedefYol);

        console.log(`Upload taşındı: ${benzersizAd}`);
        return { dosyaAdi: benzersizAd, yol: hedefYol };
    } catch (hata) {
        console.error('Upload taşıma hatası:', hata.message);
        return null;
    }
}

// 5. Güvenli rename (atomik dosya güncelleme)
async function atomikGuncelle(hedefDosya, yeniIcerik) {
    const gecici = hedefDosya + '.tmp.' + process.pid;

    try {
        // 1. Geçici dosyaya yaz
        await fs.promises.writeFile(gecici, yeniIcerik, 'utf-8');
        // 2. Atomik rename
        await fs.promises.rename(gecici, hedefDosya);
        console.log('Atomik güncelleme başarılı');
    } catch (hata) {
        // Geçici dosyayı temizle
        try { await fs.promises.unlink(gecici); } catch {}
        throw hata;
    }
}

// Test
async function testler() {
    const testDosya = path.join(testDir, 'atomik-test.txt');
    await atomikGuncelle(testDosya, 'Güvenli içerik');
    console.log('İçerik:', fs.readFileSync(testDosya, 'utf-8'));

    // Temizlik
    try {
        fs.unlinkSync(kaynak);
        fs.unlinkSync(testDosya);
        fs.rmSync(path.join(testDir, 'uploads'), { recursive: true, force: true });
    } catch {}
}
testler();

fs.rename basit ama güçlü bir fonksiyon. Dosya taşıma, yeniden adlandırma ve atomik güncelleme için kullanışlı. EXDEV hatasına karşı kopyala-sil fallback'i eklemeyi unutmayın. Kolay gelsin.
 

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

Geri
Üst