Forum: Ders Arası RSS
File Modülü
Basit örnekler...
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: File Modülü
Merhaba,

Öncelikle belirtmek istiyorum; bu modül, C'deki FILE sınıfının ve/veya C standart kütüphanesinin ve dolayısıyla core.stdc.stdio'deki ilintilerin adeta bir sarması, yani çoğumuzun bildiği şeyler. Ancak bu sınıftaki bir çok olanak öyle güzel şekillendirilmiş ki C'deki gibi sizi başıboş bırakmış değil. Çünkü FileException isminde çok güzel çalışan bir sınıfa sahip. Ayrıntılı bilgi için şuradan devam edebilirsiniz. Ama gönlünüz C'den yanaysa biraz uğraşarak kendi hata denetleme sisteminizi kurabilirsiniz de...:)

Şimdi ve ilerleyen günlerde, std.file modülü ile ilgili bir kaç basit örnek paylaşacağım. Aslında temel bazı işlemler (dosya okuma/yazma), halihazırda (linked) std.stdio içinde mevcut. Bu eleştirilen bir konu (bir çok modüle bağlantısı) olsa da biz modülün tüm özelliklerinden faydalanmak için her ikisini de tanıtıp (import) yolumuza öyle devam etmeliyiz. Dilerseniz siz de benzer örnekleri bu başlık altında paylaşabilirsiniz.

İlk olarak bir dosyanın var olup olmadığını isFile ile denetleyelim. Aynı şekilde uygulamanıza göre isDir da kullanmanız mümkün. Hataları güzelce yakalayabilmek için sıklıkla try/catch bloğundan faydalanacağız...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
import std.stdio,
       std.file;
 
void main() {
  string dosyaismi = "test.d";
  writef("Bu dosya (%s) ", dosyaismi);
 
  try {
    if(dosyaismi.isFile) {
      "var".writeln;
    }
  } catch(FileException) {
    "yok".writeln;
  }
}
Açıklama: Özellikle writef() kullanmama dikkat edin. Sadece write() kullanabilirdim ama bu sefer derleyiciye, std.stdio içindeki olduğunu belirtmem gerekiyordu. Çünkü aynı işlev std.file içinde de var. Eğer try/catch bloğunu kullanmasaydım ve dosya, yazılımın çalıştığı yerde bulunmasaydı o zaman OS'dan dönen (Windows Türkçe için) şu hata ekrana yazacaktı: "...test.c: Sistem belirtilen dosyayı bulamıyor"
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Aslında yukarıdaki örneği try/catch bloğunu kullanmadan kısa bir şekilde şöyle yapabilirdik:
  if(dosyaismi.exists) "var".writeln;
  else "yok".writeln;
Ama olası tüm senaryoları akıllı bir şekilde test etmemizi sağlamazdı. Çünkü aradığınız FAT kaydı mevcut (exist) olabilir ama bu bir dosya veya dizin olmayabilir. Yani exists() özelliği tek başına yanıltıcıdır. Eğer önceliğimiz dosyanın varlığını öğrenmek ise, yani işlemi dosya üzerinde yapacaksak şu daha iyi bir çözümdür:
import std.stdio,
       std.file;
 
void main() {
  string dosyaismi = "test";
 
  try {
    if(dosyaismi.isFile) {
      "Bu bir dosya".writeln;
    } else {
      "Bu bir dizin".writeln;
    }
  } catch(FileException) {
    "Bu isimde dosya veya dizin yok".writeln;
  }
}
Açıklama: Dikkat ederseniz try/catch bloğunda ciddi bir değişim olmadı. Sadece dosya olmaması durumunda dizin olacağını, her ikisi de yoksa hata verip catch bloğu tarafından yakalanacağını öngördük. Eğer önceliğiniz dizin ise, bu durumda isFile yerine, isDir kullanıp kodunuzu ona göre şekillendirmenizde fayda var.

Başarılar...

Dip Not: Yarın ki örneğimizde, dosya ismini değiştirme ve akıllı denetleme konusuna gireceğiz.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #4
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
import std.stdio,
       std.file,
       std.string;
 
void main(string[] dosya) {
  if(dosya.length < 2) {
    "LÜTFEN PARAMETRE KULLANIN:\n\t".
    writeln("renD eski_Adı yeni_Adı");
    return; 
  }
 
  try {
 
    dosya[1].rename(dosya[2]);
 
  } catch(FileException birHataVar) {
 
    switch(birHataVar.errno) {
      case 2:
                "Bu dosya yok: ".writeln(dosya[1]); break;
      case 5:
                "Erişim engellendi.".writeln; break;
      case 183:
                "Benzer bir dosya var!".writeln; break;
      default:
                "Belirsiz hata, kodu: ".writeln(birHataVar.errno);
    } /* Codes:
       * http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
       */
  }
}
Açıklama: Bu sefer ki örnek biraz karışık gibi görünse de temelde aynı. Belki de tek farkı ve de en önemlisi catch içindeki nesneye bir isim vermemiz. Böylece blok içerisinde nesnenin tüm özelliklerine erişebiliyoruz. Ama bu sefer, meydana gelebilecek hatalara adeta nokta atışı yapıyoruz. Çünkü switch/case içerisinde önemli hata kodlarını tanımladık. Hemen altındaki bağlantıdan bunların ne kadar çok olabileceğini görebilirsiniz ama bize sadece FileException ile ilgili olanlar yetiyor.

Bir diğer farklılık ise, komut satırından parametre almamız. Böylece bir nevi Windows OS'in "ren" komutunun tıpkısını icra etmiş olduk. O yüzden biraz daha farklı bir şeyler yaparsak konuyu terbiyelemiş olacağız...:)

Bakalım neler yapabileceğiz...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2013-10-12, 19:16.
Değişiklik nedeni: Önemsiz yazım hataları giderildi...
Avatar
Salih Dinçer #5
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sanırım bu basit bir örnek olmadı...:)
import std.stdio, std.string,
       std.file,
       std.path;
 
string yedekle(string dosya) {
  auto ismi = dosya.baseName().stripExtension();
 
  try {
    ubyte uzantısı = 1// sınır testi için : 255
    do {
      auto yeniİsmi = ismi ~ format(".%s", uzantısı);
      if(!yeniİsmi.exists) {
        dosya.rename(yeniİsmi);
        return yeniİsmi;
      }
    } while(uzantısı++)// 255'e kadar dene...
 
    "VARSAYILAN SINIR (255) AŞILDI".writeln;
 
  } catch(FileException birHataVar) {
 
    switch(birHataVar.errno) {
      case 2:
                "Bu dosya yok: ".writeln(dosya); break;
      case 5:
                "Erişim engellendi.".writeln; break;/*
      case 183:
                "Benzer bir dosya var!".writeln; break;//*/
      default:
                "Belirsiz hata, kodu: ".writeln(birHataVar.errno);
    }
  }
  return ""; // Dosya yedeklenemediği için ismi yok...
}
 
void main(string[] dosya) {
  if(dosya.length < 2) {
    "LUTFEN PARAMETRE KULLANIN:\n\t".
    writeln("removecrlf hedef_dosya");
    return; 
  }
 
  File yedek;
  try yedek = File(dosya[1].yedekle(), "r");
  catch(FileException) {
    "Dosya yedeklenemedi!".writeln;
    return;
  }
 
  File hedef;
  try hedef = File(dosya[1], "w");
  catch(FileException) {
    "Dosya tekrar kurulamıyor".writeln;
    return;
  }
 
  uint sayaç;
  foreach(satır; yedek.byLine) {
    hedef.write(satır);
    sayaç++;
  }
 
  sayaç.writeln(" adet satırbaşı karakteri silindi...");
}
Açıklama: Aslında temelde yaptığı çok basit çünkü yedekle işlevini (isim değiştirme) saymazsak, işlem yapılan dosyanın içindeki tüm satırbaşı karakterini siliyor. Çok daha basit alternatifi de mümkün ama odaklanılması gereken nokta yedekle işlevi. Bu işlevde, dikkat ederseniz büyük bir çoğunluğu önceki örnekten oluşturuldu ve gereksiz olduğu için bir hata kodu gizlendi. Yaptığı ise dosyanın uzantısını bir sayı ile değiştirmek...

Gerçi biz burada std.path modülünden de yararlanmak zorunda kaldık. Çünkü dosya ismini yoldan (path) ve uzantısından ayırmak gerekiyordu. Ayrıca dosyanın varlığı durumunda bir üstündeki sayı test ediliyor. Sonuçta 255'e kadar herhangi bir uzantıda yedekleme yapılıyor. Bunlar dışında iç içe 2 tane try/catch kullanamadığınız halde burada dolaylı olarak işlevde bir hata bulunması durumunda boş isim göndererek dıştaki try/catch tetiklenmiş oluyor.

Özetle tam denetimli akıllı bir uygulama yazmak mümkün...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #6
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sanırım burada bir şeyi atlamışım. Temel dosya açma/kapama nasıl yapılır sorusunu cevaplamadan (doğrudan diğer özelliklere girerek) konuyu anlatmaya başlamışım. Öncelikli olarak Ali hocanın derslerinden başlamanızda fayda var:

http://ddili.org/ders/d/dosyalar.html

Bir sonraki örneğimiz, bir çok alanda (internet, donanım vb.) kullanabileceğimiz bir önbellekleme çalışması olsun. Korkmayın her şey basit mantıkta olacak. İhtiyacımız olan sadece bir yığın (stack, aslında bir array~char[]) ve tam zamanında dosyadan okuma olayı (event). Bakalım becerebilecek miyiz...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
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-11-21, 19:28:34 (UTC -08:00)