Thread overview
[Kod İnceleme] Dizinde değişen kaynak dosyaları kopyalama
Jan 21, 2017
erdem
Jan 21, 2017
erdem
January 21, 2017

Bilmiyorum takip ediyor musunuz. Code review sitesinde oldukça (http://codereview.stackexchange.com/questions/152733/dijkstra-path-finding-in-c-is-15x-slower-than-c-version) ilginç (http://codereview.stackexchange.com/questions/30442/a-path-finding-algorithm-for-a-red-black-tree?rq=1) örnekler konuşuluyor. Henüz D bölümü o kadar hareketli değil gördüğüm kadarıyla ama olsun bakalım.

Ben de böyle incelenmek üzere ufak bir kod paylaşayım dedim. Bir dizinin içinde *.d kaynak dosyalarımız var. Bu program basitçe sadece değiştirilmiş dosyaları belirlediğimiz bir dizine kopyalıyor. Benim bu programda ilginç gördüğüm nokta canFind ile kayıtların karşılaştırılması. Belki daha iyi çözümler getirilebilir.

import std.stdio;
import std.file;
import std.algorithm;
import std.path;
import std.datetime;
import std.typecons;
import std.array;
import std.string;
import std.process;

SysTime sonDeğişiklikZamanı(string kütükİsmi)
{
   SysTime sonErişimZamanı;
   SysTime sonDeğişiklikZamanı;
   kütükİsmi.getTimes(sonErişimZamanı, sonDeğişiklikZamanı);
   return sonDeğişiklikZamanı;
}

string[] değişenDosyalar(SysTime kontrolZamanı)
{
   string[] degişenler;

   auto kütük = File("degisiklikler.txt", "r");

   auto sonYüklemeZamanı = SysTime.fromSimpleString(kütük.readln());

   kütük.close;

   auto dosyalar = değişenDosyalar("src/")
       .filter!(kütük => kütük[1] > sonYüklemeZamanı)
       .array;

   kütük = File("degisiklikler.txt", "w");
   kütük.writeln(kontrolZamanı);

   foreach (eleman; dosyalar)
   {
       degişenler ~= eleman[0];
       kütük.writefln("%s: %s", eleman[0], eleman[1]);
   }
   return degişenler;
}

auto değişenDosyalar(string dizinİsmi)
{
   auto dosyalar = dizinİsmi
       .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ı));
   return dosyalar;
}

void değişiklikKütüğünüOluştur()
{
   if (!exists("degisiklikler.txt"))
   {
       writeln("Kütüğü ilk kez oluşturuyorum");

       auto kütük = File("degisiklikler.txt", "w");
       SysTime yüklemeZamanı = Clock.currTime;

       kütük.writeln(yüklemeZamanı);

       auto dosyalar = değişenDosyalar("src/").array;

       foreach (eleman; dosyalar)
           kütük.writefln("%s: %s", eleman[0], eleman[1]);
   }
}

void değişenleriKaydet(string[] değişenler)
{
   if (!exists("degisenler.txt"))
   {
       auto kütük = File("degisenler.txt", "w");
       kütük.close();
   }
   else
   {
       auto kütük = File("degisenler.txt", "r");

       string satır;
       string[] eskiKayıtlar;

       while ((satır = strip(kütük.readln())) !is null)
       {
           eskiKayıtlar ~= satır;
       }

       bool değişiklikVarMı = false;

       foreach(yeniKayıt; değişenler)
       {
           if (eskiKayıtlar.canFind(yeniKayıt))
               writeln("Buldum");
           else
           {
               eskiKayıtlar ~= yeniKayıt;
               değişiklikVarMı = true;
           }
       }

       kütük.close();

       if (değişiklikVarMı)
       {
           auto çıkış = File("degisenler.txt", "w");
           foreach (kayıt; eskiKayıtlar)
               çıkış.writeln(kayıt);
           çıkış.close();
       }
   }
}

void main()
{
   değişiklikKütüğünüOluştur();

   SysTime geçerliZaman = Clock.currTime;
   string[] değişenler = değişenDosyalar(geçerliZaman);
   değişenleriKaydet(değişenler);

   foreach (dosya; değişenler)
   {
       writeln("Değişti = ", dosya);
       auto parça = dosya.findSplit("/")[2];
       auto kopyala = executeShell("cp " ~ dosya ~ " /home/erdem/gtkd/import/" ~ parça);
       if (kopyala.status != 0)
           writeln("Kopyalama başarısız");
   }

   auto kütüphaneKopyala = executeShell("cp libgtkd-3.a libgtkdgl-3.a libgtkdsv-3.a /home/erdem/gtkd/lib32");
   executeShell("make");
}

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

January 21, 2017

İnceleme için teşekkürler! :)

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

January 21, 2017

Teşekkürler, o siteden haberim yoktu.

"Kütüğü ilk kez oluşturuyorum" yazdıktan sonra bir döngüde takılıp kalıyor... diyecektim... nedeninin son satırdaki 'make' olduğunu bulabildim. :)

Even canFind filan çok kullanışlı, değil mi? Yorumlarımı 'Ali' ile işaretledim:

import std.stdio;
import std.file;
import std.algorithm;
import std.path;
import std.datetime;
import std.typecons;
import std.array;
import std.string;
import std.process;

SysTime sonDeğişiklikZamanı(string kütükİsmi)
{
   SysTime sonErişimZamanı;
   SysTime sonDeğişiklikZamanı;
   kütükİsmi.getTimes(sonErişimZamanı, sonDeğişiklikZamanı);
   return sonDeğişiklikZamanı;
}

string[] değişenDosyalar(SysTime kontrolZamanı)
{
   string[] degişenler;

   auto kütük = File("degisiklikler.txt", "r");

   auto sonYüklemeZamanı = SysTime.fromSimpleString(kütük.readln());

   // [Ali] Zararı yok ama çoğu durumda close()'a gerek yok. Hatta tekrar açtıktan sonra bu işlevin sonunda da
   // kapatmıyorsun (çünkü struct olduğu için otomatik kapanıyor).
   kütük.close;

   // [Ali] "src/"u değiştirdim ama bunu iki yerde birden yapmak zorunda kaldım. Bu işleve parametre olarak geçirilmesi
   // daha doğru olur.
   auto dosyalar = değişenDosyalar("/home/ali/benisil/")
       .filter!(kütük => kütük[1] > sonYüklemeZamanı);
   // [Ali] Aşağıdakine gerek yoktu.
   // .array;

   kütük = File("degisiklikler.txt", "w");
   kütük.writeln(kontrolZamanı);

   foreach (eleman; dosyalar)
   {
       degişenler ~= eleman[0];
       kütük.writefln("%s: %s", eleman[0], eleman[1]);
   }
   return degişenler;
}

auto değişenDosyalar(string dizinİsmi)
{
   auto dosyalar = dizinİsmi
       .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ı));
   return dosyalar;
}

// [Ali] Bu işlevin ismi yasıltıcı çünkü her zaman oluşturmuyor. Ben böyle işlevleri İngilizce'de 'ensure' ile
// başlatıyorum: ensureFalancaFileExists() gibi. Türkçe'de ne demeli?
void değişiklikKütüğünüOluştur()
{
   if (!exists("degisiklikler.txt"))
   {
       writeln("Kütüğü ilk kez oluşturuyorum");

       auto kütük = File("degisiklikler.txt", "w");
       SysTime yüklemeZamanı = Clock.currTime;

       kütük.writeln(yüklemeZamanı);

       auto dosyalar = değişenDosyalar("/home/ali/benisil/");
       // [Ali] Aşağıdakine gerek yoktu.
       // .array;

       // [Ali] Bu kişisel bir konu ama ben tek deyim bile bulunsa hiçbir kapsamı küme parantezsiz bırakmıyorum.
       foreach (eleman; dosyalar)
           kütük.writefln("%s: %s", eleman[0], eleman[1]);
   }
}

void değişenleriKaydet(string[] değişenler)
{
   if (!exists("degisenler.txt"))
   {
       auto kütük = File("degisenler.txt", "w");
       kütük.close();
   }
   else
   {
       auto kütük = File("degisenler.txt", "r");

       string satır;
       string[] eskiKayıtlar;

       while ((satır = strip(kütük.readln())) !is null)
       {
           eskiKayıtlar ~= satır;
       }

       bool değişiklikVarMı = false;

       foreach(yeniKayıt; değişenler)
       {
           if (eskiKayıtlar.canFind(yeniKayıt))
               writeln("Buldum");
           else
           {
               eskiKayıtlar ~= yeniKayıt;
               değişiklikVarMı = true;
           }
       }

       kütük.close();

       if (değişiklikVarMı)
       {
           auto çıkış = File("degisenler.txt", "w");
           foreach (kayıt; eskiKayıtlar)
               çıkış.writeln(kayıt);
           çıkış.close();
       }
   }
}

void main()
{
   değişiklikKütüğünüOluştur();

   SysTime geçerliZaman = Clock.currTime;
   string[] değişenler = değişenDosyalar(geçerliZaman);
   değişenleriKaydet(değişenler);

   foreach (dosya; değişenler)
   {
       writeln("Değişti = ", dosya);
       auto parça = dosya.findSplit("/")[2];
       auto komut = "cp " ~ dosya ~ " /home/ali/benisil2/" ~ parça;

       // [Ali] Aşağıdaki komut şunun gibi bir şeye dönüşüyordu:
       //
       //   cp /home/ali/benisil/a.d /home/ali/benisil2/home/ali/benisil/a.d
       //
       // Hedefte öyle bir klasör olmadığından da başarısız oluyordu. Bu noktada std.file.mkdirRecurse'ü çağırmak
       // isteyebilirsin.
       writeln(komut);

       auto kopyala = executeShell(komut);
       if (kopyala.status != 0) {
           writeln("Kopyalama başarısız");
       }
   }

   auto kütüphaneKopyala = executeShell("cp libgtkd-3.a libgtkdgl-3.a libgtkdsv-3.a /home/erdem/gtkd/lib32");
   // [Ali] Tabii bu sonucu da denetlemek gerekiyor.

   // [Ali] Aşağıdaki satır ben çok uğraştırdı çünkü kendim senin programını 'make' ile oluşturduğumdan, ve oluşan
   // program otomatik olarak işletildiğinden, bütün işlemler sonsuza kadar devam ediyordu. :)
   //
   // executeShell("make");
}

Ali

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