Forum: D Programlama Dili RSS
Dosyadan bayt okumak
Page:  previous  1  2 
zafer #16
Member since Jul 2009 · 356 posts · Location: Ankara
Group memberships: Üyeler
Show profile · Link to this post
In reply to post ID 4762
Ali bu harika bilgiler için teşekkür ederim. Özellikle scope() örneği çok güzeldi.

Mp3 tag bilgisi kodunu çalıştırmayı başardım ancak aklıma takılan bazı satırlarla ilgili sorularım olacak, bugün işler biraz yoğun, bende soruları bir toparlayıp hazırlardıkça buraya eklerim. Vakit ayırdığın için tekrar teşekkürler.
http://www.zafercelenk.net - site    ||    https://github.com/zafer06 - depo
zafer #17
Member since Jul 2009 · 356 posts · Location: Ankara
Group memberships: Üyeler
Show profile · Link to this post
In reply to post ID 4734
Merhaba Ali, kod ile ilgili aklıma takılanları satır satır yazıyoruz. Açıklama getirisen çok sevinirim.

immutable dosyaYeri = dosya.tell();    // <-- değişkende sakla
scope(exit) dosya.seek(dosyaYeri, SEEK_SET);

Bu kodlarla amacımız metotun çıkışında dosyayı ilk haline getirip bırakmak ama buna neden ihtiyaç duyduk
gerçi bu sayde scope()'u tanımış olduk ama işlemin sonunda dosya.close() ile dosyayı kapatmak daha doğru
olmaz mıydı?

ID3v1Pakedi[1] paketler;
dosya.rawRead(paketler);
 
ID3v1Pakedi paket = paketler[0];

Burada paketler isminde tek elemanlı bir dizi oluşturuyoruz ve rawRead() metoduna bu diziyi gönderiyoruz.
Sonrasında ise dizideki tek elemanı bir pakete aktarıyoruz.Bunun yerine paket isminde bir değşken oluşturup göndersek olmaz mı? Bu belkide rawRead() metodunun arkaplanda fread (http://cplusplus.com/reference/clibrary/cstdio/fread/) metodunu kullanması ile alakalı bir durumudur. (http://www.dlang.org/phobos/std_stdio.html#rawRead)
http://www.zafercelenk.net - site    ||    https://github.com/zafer06 - depo
acehreli (Moderator) #18
User title: Ali Çehreli
Member since Jun 2009 · 2279 posts
Group memberships: Genel Moderatörler, Üyeler
Show profile · Link to this post
Quote by zafer:
immutable dosyaYeri = dosya.tell();    // <-- değişkende sakla
scope(exit) dosya.seek(dosyaYeri, SEEK_SET);

Bu kodlarla amacımız metotun çıkışında dosyayı ilk haline getirip bırakmak ama buna neden ihtiyaç duyduk
gerçi bu sayde scope()'u tanımış olduk ama işlemin sonunda dosya.close() ile dosyayı kapatmak daha doğru
olmaz mıydı?

Bu işlev dosyayı kendisi açmadığı için kapatması da doğru olmazdı.

Tabii işlevi dosyayı kendisi açacak biçimde de tasarlamış olabilirdik. Dosya ismini verirdik, açardı, pakedi okurdu, ve döndürürdü. (Ara not: Ben o zaman bile dosya.close()'u açıkça çağırmazdım. Bir C++ programcısı olarak programları sonlandırıcı işlevler etrafında düşünüyorum. File'ın sonlandırıcısı zaten dosyayı kapattığı için açıkça kapatmaya gerek yok. Açıkça kapatmak, hemen tekrar örneğin başka bir erişim hakkı ile açılacaksa şarttır. Ama açıkça kapatılmasında da hiç sakınca yoktur tabii.)

Ancak, işlevin dosya ismi almasını beğenmemiştim:

  • Dosya açmak göreceli olarak masraflıdır. Zaten açık bir dosya varsa onu kullanmak daha etkin olur. (O yüzden de dosyayı baştaki durumuna getirmek için yapmamız gereken tek şey seek()'i çağırmak.)

  • Bizi çağıran kodun dosyayı zaten açmış olmasını beklemek mantıklıdır çünkü ID3v1 olup olmadığına ancak dosyanın bazı yerlerini okuyarak karar vermiştir. Yani bizi çağırdığına göre dosyayı açıp içine zaten bakmıştır.

  • En önemlisi basitlik. (Basitlik yazılım tasarımlarının en baş ilkesi olmalıdır.) İşlevin şimdiki tanımı şöyle: "dosyanın ID3v1 pakedini okur ve döndürür; paket yasal değilse hata atar." Eğer dosya ismi alsaydı birazcık daha karmaşık olurdu: "dosyayı açar, ... vs. ...". Ama bu sefer dosya açılamadığında da hata atması gerekirdi. Yani işler azıcık da olsa karmaşıklaşmış olurdu. (Bu maddenin o kadar inandırıcı olmadığını kabul ediyorum ama bana File alan işlev daha az karmaşık geliyor. En azından içinde dosya açma satırı yok. :))

Bunlara karşılık senin fikrin de geçerli: dosya ismini alıp dosyayı açıp kapatsak seek() ile baştaki durumuna getirmek gibi bir derdimiz olmazdı. O da kabul. Belki de beni yönlendiren şey gerçekten de dosya açma masrafıydı. Ayrıca işletim sistemleri aynı anda belirli sayıda dosyadan fazlasını açtırmazlar. Zaten açıksa onu kullanmak iyidir.

ID3v1Pakedi[1] paketler;
dosya.rawRead(paketler);
 
ID3v1Pakedi paket = paketler[0];

Burada paketler isminde tek elemanlı bir dizi oluşturuyoruz ve rawRead() metoduna bu diziyi gönderiyoruz.

Biraz garip yapmışlar: rawRead() şablon olduğu için her tür dizi olarak okuyabiliyor. Ama nedense tek değişkene okuyan yüklemesini yapmamışlar. Onun için tek paket bulunduğunda bile dizi olarak tanımlamak gerekiyor.

Sonrasında ise dizideki tek elemanı bir pakete aktarıyoruz.Bunun yerine paket isminde bir değşken oluşturup göndersek olmaz mı?

Tek değişkene yukarıdaki nedenden okuyamadık. Ama söylediğinin son bölümünü öyle yaptık zaten: paket isminde değişken oluşturup onu gönderdik. Olsa olsa, ondan vazgeçip hep paketler[0]'ı kullanırdık:

        enforce (paketler[0].TAG == "TAG",
                 format("'%s', bir ID3v1 dosyası değil!", dosya.name()));
 
        return paketler[0];

paket değişkenini okunaklılığı arttıracağını düşünerek eklemiştim. Yoksa bir tane olduğunu bildiğimiz pakedi dizi gibi kullanmak garip gelmişti. Ama bunda bir tane kopya eksik olduğu için daha hızlı işleyecektir. (O konuda da derleyiciye güvenmiştim: Derleyici, paket değişkenini gerçekten oluşturmak yerine doğrudan paketler[0]'ı kullanabilir. Tabii bunu programın davranışında bir farklılığa neden olmayacağını kanıtlayabilirse yapar.)

Yapılabilse, daha iyisi şu olurdu:

        alias paketler[0] paket;    // <-- derleme HATASI 

O zaman paketler[0]'a paket ismini vermiş olurduk. Ama "bir ifade alias yapılamaz" gibi bir hata mesajıyla derlenemiyor.

Başka bir hayal, paket'in paketler[0]'ın referansı olduğunu belirtmek olurdu:

        ref ID3v1Pakedi paket = paketler[0];    // <-- derleme HATASI 

Ama D'de öyle yerel değişken referansları yok. (C++'ta & karakteri ile olabilirdi.) (D'de işlev parametreleri ref olabiliyor.)

Aklıma gelen son yöntem gösterge kullanmak:

        ID3v1Pakedi * paket = &paketler[0];
 
        enforce (paket.TAG == "TAG",
                 format("'%s', bir ID3v1 dosyası değil!", dosya.name()));
 
        return *paket;

Baştaki paket değişkeninin oluşturulma masrafından kurtulmuş olduk. Bunun gerçekten kazançlı olup olmadığı denenerek bulunabilir.

Ama bence hiçbir program dosyanın sonundan ID3v1 pakedi okuyan işlevin içindeki bir kopya yüzünden yavaşlamaz. Dosya ne de olsa bir işlemde kullanılacaktır. O işlemler yanında 128 baytlık basit bir struct kopyası farkedilmez. :)

Ali
zafer #19
Member since Jul 2009 · 356 posts · Location: Ankara
Group memberships: Üyeler
Show profile · Link to this post
Ali, kodlar gayet güzel, benim sorumdaki amaç oradaki dizi tanımlama işlemini tam olarak anlamadığımdan dolayıdı yoksa genelde bende senle aynı fikirdeyim. Yalnız üçüncü maddeye farklı bir açıdan bakılabilir.

Quote by acehreli:
  • En önemlisi basitlik. (Basitlik yazılım tasarımlarının en baş ilkesi olmalıdır.) İşlevin şimdiki tanımı şöyle: "dosyanın ID3v1 pakedini okur ve döndürür; paket yasal değilse hata atar." Eğer dosya ismi alsaydı birazcık daha karmaşık olurdu: "dosyayı açar, ... vs. ...". Ama bu sefer dosya açılamadığında da hata atması gerekirdi. Yani işler azıcık da olsa karmaşıklaşmış olurdu. (Bu maddenin o kadar inandırıcı olmadığını kabul ediyorum ama bana File alan işlev daha az karmaşık geliyor. En azından içinde dosya açma satırı yok. :))

Buradaki basitlik kavramına katılıyorum ve bende yapılan işlemlerin bir arada bulunması açısından belki metodun sadece dosya yolunu alıp dosyayı kendi içinde açıp işlemleri yapmasının daha güzel olabileceğini düşünüyorum. Ancak bu kesinlikle sadece başka bir bakış acısı bir tartışma konusu olacak bir şey değil.

Yardımlar için teşekkürler.
http://www.zafercelenk.net - site    ||    https://github.com/zafer06 - depo
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please note the verification code from the picture into the text field next to it.
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Page:  previous  1  2 
Not logged in. · Lost password · Register
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Current time: 2012-05-18, 10:05:13 (UTC -07:00)