Thread overview
Dizinde değişiklik olmuş dosyaların listesini almak
Dec 20, 2016
erdem
Dec 20, 2016
erdem
Dec 20, 2016
zafer
Dec 25, 2016
erdem
Jan 22, 2017
erdem
December 20, 2016

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.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 20, 2016

Ali bey çok teşekkürler.

'spanMode''u da 'DFS' kullanacak şekilde değiştirdim. Tekrar bakıyorum.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 20, 2016

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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 20, 2016

Ş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.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 25, 2016

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.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 26, 2016

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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 22, 2017

Peki bu işlev her zaman bir tamsayı mı döndürecek. Program çağrıldığı zaman 42'leri de yazıyor ;-)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 22, 2017

:) Tabii, hem foo içindeki writeln'in hem de bütün .each ifadesinin kaldırılması gerek.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]