Forum: Ders Arası RSS
Dizinde değişiklik olmuş dosyaların listesini almak
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 959 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Dizinde değişiklik olmuş dosyaların listesini almak
Bir dizin içinde değişiklik olmuş dosyaların listesini almak için nasıl bir yol izleyebiliriz acaba. Örneğin veri isimli boş bir dizinimiz var.

/veri/

3 tane kütük ekledik

/veri/
/veri/ilk.html
/veri/ikinci.html
/veri/üçüncü.html


Şimdi ilk duruma göre 3 tane kütük olduğu için 3 kütük ismini ve yolunu da almalıyız. Sonra bir kütük daha ekliyorum ve ikinci kütüğü değiştiriyorum.

/veri/
/veri/ilk.html
/veri/ikinci.html
/veri/üçüncü.html
/veri/dördüncü.html


Şimdi de 2 ve 4 numaralı kütükleri vermeli.

Bunun dışında dosya uzantısını programa paremetre olarak geçerek örneğin sadece değişmiş *.html, *.d şeklinde dosya türüne göre seçim yaptırabilmeliyiz. Sonra tek bir kütük adını da paremetre olarak ekleyebilmeliyiz. Örneğin sitemap.xml şeklinde. Bu durumda sitemap.xml takip edilecek kütükler listesine eklenirken diğer *.xml uzantılı kütüklerin takibini yapmayacağız.

Programın başlangıcında dizindeki dosyaların listesini ve boyutunu bir kütüğe atıp, program sonunda tekrar alarak bu ikisini karşılaştırsak mı acaba. Bir kütüğün boyutu değişmişse değişiklik olduğunu gösterir değil mi? Kütüğün boyutu değişmeden değişiklik yapılabilir mi.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4515 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Dosya listesinin son halini tutmak senin görevin. Dosyada yapılan her değişiklik dosyanın modification time (son değişiklik zamanı) özelliğinden anlaşılabilir. D bunu C kütüphanesinin stat işlevinden öğreniyor.

Aklıma ilk gelen yöntem aşağıda. Verilen klasördeki .d dosyalarından 1 Aralık 2016'dan sonra değişmiş olanlarını buluyor:
import std.stdio: writeln, writefln;
import std.file: getTimes;
import std.algorithm: filter, map, each;
import std.path: dirEntries, SpanMode, extension;
import std.datetime: SysTime, DateTime;
import std.typecons: tuple;
 
// getTimes, parametrelerine atayan (yan etki üreten) bir işlev olduğundan map ile kullanışlı değil.
// Bu işlevi map ile kolay kullanılabilsin diye yazdım.
SysTime sonDeğişiklikZamanı(string dosyaAdı) {
    SysTime sonErişimZamanı;
    SysTime sonDeğişiklikZamanı;
    dosyaAdı.getTimes(sonErişimZamanı, sonDeğişiklikZamanı);
    return sonDeğişiklikZamanı;
}
 
void main(string[] args) {
    string klasör = (args.length > 1 ? args[1] : ".");
    const arananZaman = SysTime(DateTime(2016, 12, 1));
 
    writeln("\n=== Zincirleme yöntemle ===");
    klasör
        .dirEntries(SpanMode.shallow)
        .filter!(isim => isim.extension == ".d")
        .map!(isim => tuple(isim, isim.sonDeğişiklikZamanı))
        .filter!(çokuzlu => çokuzlu[1] > arananZaman)
        .each!writeln;
 
    writeln("\n=== Geleneksel yöntemle ===");
    foreach (dosyaAdı; dirEntries(klasör, SpanMode.shallow)) {
        if (extension(dosyaAdı) == ".d") {
            const değişiklikZamanı = sonDeğişiklikZamanı(dosyaAdı);
            if (değişiklikZamanı > arananZaman) {
                writefln("%s: %s", dosyaAdı, değişiklikZamanı);
            }
        }
    }
}
Ali
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 959 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ali bey çok teşekkürler.

spanMode'u da DFS kullanacak şekilde değiştirdim. Tekrar bakıyorum.
zafer #4
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Şu filter! olanağı gerçekten çok kullanışlı. Bana biraz C# dilindeki LINQ olanağını hatırlatıyor. Ancak kullanımı ondan daha basit ve daha pratik geldi bana.
https://github.com/zafer06 - depo
erdem (Moderatör) #5
Üye Tem 2009 tarihinden beri · 959 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Biraz öğrenmek amacıyla çokuzlu yaptıktan sonra nasıl expand ile genişletebiliriz diye düşünüyordum.
    ("yerel/")
        .dirEntries(SpanMode.depth)
        .filter!(kütük => kütük.extension == ".html")
        .map!(kütük => tuple(kütük, kütük.sonDeğişiklikZamanı))
        .map!(kütük => kütük[0])
        .each!writeln;
 
    auto dosya = ("yerel/")
        .dirEntries(SpanMode.depth)
        .filter!(kütük => kütük.extension == ".html")
        .map!(kütük => tuple(kütük, kütük.sonDeğişiklikZamanı))
        .array;
 
    foreach (eleman; dosya)
        writeln(eleman.expand);
Tekrar diziye çevirip foreach ile yazdırınca oluyor ama UFCS ile yapamadım.

    .map!(kütük => kütük[0])

yerine kütük.expand yazmaya çalışınca hata veriyor. Bir aralığın içindeki çokuzlulara nasıl erişebiliriz acaba.

Bir yapıdan çokuzlu elde edilebiliyordu. Bir çokuzlu ile bir yapı ilklendirilebilir mi.
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4515 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
expand, çokuzluyu bileşenlerine ayırıyor. Ürettiği şey, AliasSeq'in kullanılabildiği yerlerde kullanılabilen virgüllerle ayrılmış bir liste. Bu tür listeler kendi başlarına kullanılamıyorlar ama işlev listesi, şablon parametre listesi, dizi ilkleme listesi gibi yerlerde kullanılabiliyorlar.

Örneğin, kütük.expand'in döndürdüğünü, onun elemanlarını alabilen bir işleve gönderebilirsin. map tembel olduğundan, işleyişini görmek için sonuna bir de .each ekledim:
int foo(string dizgi, SysTime zaman) {
    writefln("foo, '%s' ve '%s' ile çağrıldı.", dizgi, zaman);
    return 42;
}
 
// ...
 
    ("./")
        .dirEntries(SpanMode.depth)
        .filter!(kütük => kütük.extension == ".d")
        .map!(kütük => tuple(kütük, kütük.sonDeğişiklikZamanı))
        .map!(kütük => foo(kütük.expand))
        .each!(değer => writeln(değer));
Ali
erdem (Moderatör) #7
Üye Tem 2009 tarihinden beri · 959 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Peki bu işlev her zaman bir tamsayı mı döndürecek. Program çağrıldığı zaman 42'leri de yazıyor  ;-)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4515 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
:) Tabii, hem foo içindeki writeln'in hem de bütün .each ifadesinin kaldırılması gerek.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-10-23, 15:22:39 (UTC -07:00)