C Sharp Programlama Dili/Temel I/O işlemleri

Ders 18. Temel I/O işlemleri


I/O İngilizce Input/Output'un kısaltmasıdır, Türkçeye girdi/çıktı olarak çevirebiliriz. Ancak I/O bilgisayar ve programlama dünyasında artık bir terim hüviyetine kavuştuğu için I/O olarak kullanmayı tercih ediyorum. Dosya kaydetme, ekrana ya da yazıcıya bilgi yazdırma, klavyeden bilgi girişi birer I/O işlemleridir. I/O işlemlerini System.IO isim alanının altındaki çeşitli sınıflarla yaparız. Şimdi isterseniz lafı fazla uzatmadan dosya ve klasör işlemleriyle ilgili sınıflara geçelim.

Directory sınıfı

değiştir

Directory sınıfının hiçbir özelliği yoktur, System.IO altında bulunur, sadece static metotlar içerir.

DirectoryInfo CreateDirectory(string adres)

değiştir

adres ile belirtilen adreste bir klasör oluşturur ve bu klasör bilgilerini bir DirectoryInfo nesnesi olarak tutar. Programımızın çalıştığı klasörde bir klasör oluşturmak için sadece klasörün adını yazmak yeterlidir. Örnekler:

Directory.CreateDirectory(@"C:\WINDOWS\deneme");

Bu kod C:\WINDOWS altında deneme isimli bir klasör oluşturur.

Directory.CreateDirectory("deneme");

Bu kod programın çalıştığı klasörde deneme isimli bir klasör oluşturur.

Directory.CreateDirectory(@"..\deneme");

Bu kod programın çalıştığı klasörün bir üst klasöründe deneme isimli bir klasör oluşturur.

Directory.CreateDirectory(@"..\..\deneme");

Bu kod programın çalıştığı klasörün iki üst klasöründe deneme isimli bir klasör oluşturur. .. sayıları bu şekilde artırılabilir. Bu tür bir adres belirtme şekli bütün diğer metotlarda da geçerlidir. Ayrıca bu ve diğer bütün metotlarda da adres diye tarif ettiğimiz veriye dosya/klasörün adı da dâhildir.

void Delete(string adres)

değiştir

Belirtilen adresteki boş klasörü silmek için kullanılır. Başka bir kullanımı daha vardır.

void Delete(string adres,bool a)

Bu metot ile eğer a true ise belirtilen adresteki klasör, içindeki bütün dosya ve klasörlerle birlikte silinir.

bool Exists(string adres)

değiştir

Belirtilen adresteki klasörün olup olmadığını bool cinsinden tutar. Klasör varsa true, yoksa false döndürür.

string GetCurrentDirectory()

değiştir

Çalışan programın hangi klasörde olduğunu verir. Örneğin Windows'taysak C:\WINDOWS'u tutar.

string[] GetDirectories(string adres)

değiştir

Belirtilen adresteki bütün klasörleri adresleriyle birlikte bir string dizisi olarak tutar.

string GetDirectoryRoot(string adres)

değiştir

Belirtilen adresteki klasörün kök dizin bilgisini verir. Örneğin adres C:\Program Files\CONEXANT\CNXT_MODEM_HDAUDIO_SprtHD5m ise C:\ değerini döndürür.

string[] GetFiles(string adres)

değiştir

Belirtilen adresteki dosyaları adresleriyle birlikte string dizisi olarak tutar. Bu ve benzer metotlarda liste İngilizce alfabetik sırasına göredir. GetFiles() metodunun bir prototipi daha vardır:

string[] GetFiles(string adres,string dosya)

Adresteki dosya(lar) adresleriyle birlikte string dizisi olarak tutulur. Dosya isminde joker karakterleri (*, ?) kullanılabilir.

string[] GetFileSystemEntries(string adres)

değiştir

Belirtilen adresteki bütün dosya ve klasörleri adresleriyle birlikte bir string dizisi olarak tutar.

DateTime GetLastAccessTime(string adres)

değiştir

Belirtilen adresteki dosya ya da klasöre en son ne zaman erişildiğini DateTime türünden tutar.

DateTime GetLastWriteTime(string adres)

değiştir

Belirtilen adresteki dosya ya da klasörün en son ne zaman değiştirildiğini DateTime türünden tutar.

DateTime GetCreationTime(string adres)

değiştir

Belirtilen adresteki dosya ya da klasörün ne zaman oluşturulduğunu DateTime türünden tutar.

string[] GetLogicalDrives()

değiştir

Bilgisayardaki bütün sürücüleri bir string dizisi olarak tutar. Bu sürücülere her türlü sabit disk, CD-ROM sürücü, flash disk vb. dâhildir.

DirectoryInfo GetParent(string adres)

değiştir

Belirtilen adresin bir üst klasörünü DirectoryInfo nesnesi olarak döndürür.

void Move(string kaynak_adres,string hedef_adres)

değiştir

Dosya ve klasörleri bir konumdan başka bir konuma taşır. Örnekler:

Directory.Move(@"C:\Documents and Settings\Bekir Oflaz\Belgelerim\Örnek dosya.rtf",@"C:\Web\deneme.rtf");

Bu kod C:\Documents and Settings\Bekir Oflaz\Belgelerim altındaki Örnek dosya.rtf dosyasını C:\Web konumuna deneme.rtf adıyla taşır.

Directory.Move(@"C:\Web",@"C:\Documents and Settings\Bekir Oflaz\Belgelerim\internet");

Bu kod sürücü klasöründeki Web klasörünü tüm içeriğiyle birlikte C:\Documents and Settings\Bekir Oflaz\Belgelerim klasörüne internet adıyla taşır. Eğer hedef klasörde aynı adlı dosya ya da klasör varsa çalışma zamanı hatası alırsınız.

void SetLastAccessTime(string adres, DateTime zaman)

değiştir

Belirtilen adresteki dosya ya da klasörün en son erişim zamanını zaman olarak değiştirir.

void SetLastWriteTime(string adres, DateTime zaman)

değiştir

Belirtilen adresteki dosya ya da klasörün en son değiştirilme zamanını zaman olarak değiştirir.

void SetCreationTime(string adres, DateTime zaman)

değiştir

Belirtilen adresteki dosya ya da klasörün oluşturulma zamanını zaman olarak değiştirir.

void SetCurrentDirectory(string adres)

değiştir

Programın çalıştığı klasörü belirtilen adres ile değiştirir.

File sınıfı

değiştir

File sınıfındaki birçok metot Directory sınıfında da vardır, tek farkları aynı görevleri dosyalar için yerine getirmeleridir. Bu metotlar şunlardır: Exists(), Delete(), GetCreationTime(), GetLastAccessTime(), GetLastWriteTime(), Move(), SetCreationTime(), SetLastAccessTime(), SetLastWriteTime(). Şimdi File sınıfının Directory sınıfında olmayan metotlarına sıra geldi.

StreamWriter AppendText(string adres)

değiştir

Adreste belirtilen dosya için daha sonra göreceğimiz bir StreamWriter nesnesi oluşturur.

void Copy(string kaynak,string hedef)

değiştir

Kaynakta belirtilen dosya hedefe kopyalanır. Kopyalamada bir isim çakışması söz konusuysa, yani sizin kopyalama yapmak istediğiniz klasörde zaten aynı isimli bir dosya varsa çalışma zamanı hatası alırsınız. Bunu önlemek içinse;

void Copy(string kaynak,string hedef,bool a)

Burada a true olursa eğer hedef klasörde aynı adlı dosya varsa üstüne yazılır. a false yapılırsa iki parametreli hâlinden farkı kalmaz.

FileStream Create(string adres,int tampon)

değiştir

Belirtilen adresteki dosya oluştururlur ve dosyaya ilişkin FileStream nesnesi döndürülür. tampon yazılmazsa yani sadece bir parametre yazılırsa varsayılan tampon miktarı kullanılır.

StreamWriter CreateText(string adres)

değiştir

Belirtilen adreste üzerine yazmak için bir text dosyası oluşturulur ve dosyaya ilişkin StreamWriter nesnesi döndürülür.

FileAttributes GetAttributes(string adres)

değiştir

Belirtilen adresteki dosya ya da klasörün FileAttributes enumu cinsinden özniteliği döndürülür. FileAttributes enum sabiti şu sözcükleri içerir: Archive, Compressed, Device, Directory, Encrypted, Hidden, Normal, NotContentIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, Temporary. Bir dosya ya da klasörün birden fazla özniteliği olabilir. Bu durumda öznitelikler virgülle ayrılır.

Üç farklı aşırı yüklenmiş çeşidi vardır. Bunlar:

FileStream Open(string adres, FileMode a)
FileStream Open(string adres, FileMode a, FileAccess b)
FileStream Open(string adres, FileMode a, FileAccess b,FileShare c)

Open() metodu belirtilen adresteki dosyayı açar ve dosyaya ilişkin FileStream nesnesini döndürür. FileMode, FileAccess ve FileShare System.IO isim alanında bulunan enumlardır ve dosyanın ne şekilde açılacağını ve üzerinde ne şekilde işlem yapılacağını belirtirler.

FileMode enumunda bulunan sözcükler

değiştir

Append Açılan dosyanın sonuna ekleme yapmak için kullanılır. Eğer dosya bulunmazsa oluşturulur.
Create Yeni dosya oluşturmak için kullanılır. Zaten dosya varsa üzerine yazılır.
CreateNew Yeni dosya oluşturmak için kullanılır, belirtilen dosya mevcutsa çalışma zamanı hatası verdirir.
Open Dosyayı açmak için kullanılır.
OpenOrCreate Belirtilen dosya varsa açılır, yoksa yenisi oluşturulur.
Truncate Belirtilen dosya açılır ve içi tamamen silinir.

FileAccess enumunda bulunan sözcükler

değiştir

Read Dosya okumak için kullanılır.
ReadWrite Dosya okunmak ve yazılmak üzere açılır.
Write Dosya sadece yazılmak için açılır.

FileShare enumunda bulunan sözcükler

değiştir

Inheritable Dosyanın child (yavru) prosesler tarafından türetilebilmesini sağlar.
None Dosyanın aynı anda başka prosesler tarafından açılmasını engeller.
Read Dosyanın aynı anda başka proseslerce de açılabilmesini sağlar.
ReadWrite Dosyanın aynı anda başka proseslerce de açılıp, okunup, yazılabilmesini sağlar.
Write Dosyaya aynı anda başka proseslerce yazılabilmesini sağlar.

FileStream OpenRead(string adres)

değiştir

Belirtilen dosyayı yalnızca okumak için açar ve dosyaya ilişkin FileStream nesnesini döndürür.

StreamReader OpenText(string adres)

değiştir

Belirtilen dosyayı yalnızca text modunda okumak için açar ve dosyaya ilişkin StreamReader nesnesini döndürür.

FileStream OpenWrite(string adres)

değiştir

Belirtilen dosyayı yazma modunda açar ve dosyaya ilişkin FileStream nesnesini döndürür.

DirectoryInfo sınıfı

değiştir

DirectoryInfo sınıfı Directory sınıfının aksine static olmayan metot ve özellikleri içerir. Önce özellikleri bir örnek üzerinde görelim:

using System;
using System.IO;
class DirectoryInfoSinifi
{
   static void Main()
   {
      string adres=@"C:\WINDOWS";
      DirectoryInfo d=new DirectoryInfo(adres);
      Console.WriteLine("Özellikler: "+d.Attributes);
      Console.WriteLine("Oluşturulma tarihi: "+d.CreationTime);
      Console.WriteLine("Var mı? "+d.Exists);
      Console.WriteLine("Uzantı: "+d.Extension);
      Console.WriteLine("Tam adres: "+d.FullName);
      Console.WriteLine("Son erişim zamanı: "+d.LastAccessTime);
      Console.WriteLine("Son değişiklik zamanı: "+d.LastWriteTime);
      Console.WriteLine("Klasör adı: "+d.Name);
      Console.WriteLine("Bir üst klasör: "+d.Parent);
      Console.WriteLine("Kök dizin: "+d.Root);
   }
}

Şimdi de DirectoryInfo sınıfının metotlarına geçelim. Bu metotların tamamı static değildir. Bu metotların çalışması için gereken adres bilgisi, kendisine ulaşılması için kullanılan DirectoryInfo nesnesindedir.

void Create()

değiştir

Klasör oluşturur.

DirectoryInfo CreateSubdirectory(string adres)

değiştir

Belirtilen adreste bir alt dizin oluşturur. Örneğin C:\deneme altında \deneme2\deneme3 dizini oluşturmak için şu kodları yazarız.

string adres=@"C:\deneme";
DirectoryInfo d=new DirectoryInfo(adres);
d.Create();
DirectoryInfo alt=d.CreateSubdirectory("deneme2");
alt.CreateSubdirectory("deneme3");

Gördüğünüz gibi CreateSubdirectory metodu kendisine ulaşılan nesne içinde parametredeki klasörü oluşturuyor ve oluşturduğu klasörü de DirectoryInfo nesnesi olarak döndürüyor.

İki farklı aşırı yüklenmiş versiyonu vardır.

void Delete()
void Delete(bool a)

Birincisinde klasör boşsa silinir, ikincisinde a true ise klasör, içindeki her şeyle silinir.

DirectoryInfo[] GetDirectories()

değiştir

İlgili klasörde bulunan bütün dizinleri bir DirectoryInfo dizisinde tutar.

FileInfo[] GetFiles()

değiştir

İlgili klasörde bulunan bütün dosyaları bir FileInfo dizisinde tutar.

FileSystemInfo[] GetFileSystemInfos()

değiştir

İlgili klasördeki bütün dosya ve klasörler bir FileSystemInfo dizisinde tutulur.

void MoveTo(string hedef)

değiştir

İlgili dizin, içindeki tüm dosya ve klasörlerle beraber hedefe taşınır.

void Refresh()

değiştir

İlgili klasörün özelliklerini diskten tekrar yükler.

NOT: Bütün taşıma ve kopyalama işlemlerinde kaynak ve hedef aynı sürücüde olmalıdır.

FileInfo sınıfı

değiştir

Önce özellikleri bir örnek üzerinde görelim. Kodu yazmadan önce kendiniz C:\WINDOWS klasöründe deneme.txt dosyasını oluşturun.

using System;
using System.IO;
class FileInfoSinifi
{
   static void Main()
   {
      string adres=@"C:\WINDOWS\deneme.txt";
      FileInfo d=new FileInfo(adres);
      Console.WriteLine("Öznitelikler: "+d.Attributes);
      Console.WriteLine("Oluşturulma tarihi: "+d.CreationTime);
      Console.WriteLine("Var mı? "+d.Exists);
      Console.WriteLine("Uzantı: "+d.Extension);
      Console.WriteLine("Tam adres: "+d.FullName);
      Console.WriteLine("Son erişim zamanı: "+d.LastAccessTime);
      Console.WriteLine("Son değişiklik zamanı: "+d.LastWriteTime);
      Console.WriteLine("Boyut: "+d.Length);
      Console.WriteLine("Klasör adı: "+d.Name);
      Console.WriteLine("Bulunduğu klasör: "+d.DirectoryName);
   }
}

Şimdi metotlara geçelim. FileInfo sınıfı File sınıfındaki AppendText(), Create(), CreateText(), Delete(), Open(), OpenRead(), OpenText() ve OpenWrite() metotlarını içerir. Bunları tekrar anlatmayacağım. File sınıfında olmayan metotlarsa;

İki aşırı yüklenmiş versiyonu vardır:

FileInfo CopyTo(string hedef)
FileInfo CopyTo(string hedef,bool a)

Birincisinde ilgili dosya hedefe kopyalanır. Hedefte aynı adlı dosya varsa çalışma zamanı hatası alırsınız. İkincisinde a true ise, hedefte aynı adlı dosya varsa üzerine yazılır.

void MoveTo(string hedef)

değiştir

İlgili dosya hedefe taşınır.

void Refresh()

değiştir

İlgili dosyanın bilgileri diskten tekrar alınır.

Path sınıfı

değiştir

Path sınıfı çeşitli işlemler yapan static üye elemanlara sahiptir. Örnek program:

using System;
using System.IO;
class PathSinifi
{
   static void Main()
   {
      string adres=@"C:\dizin\deneme.txt";
      Console.WriteLine("Uzantı: "+Path.GetExtension(adres));
      string yeniAdres=Path.ChangeExtension(adres,"jpg");
      Console.WriteLine("Yeni uzantı: "+Path.GetExtension(yeniAdres));
      string adres2=@"C:\klasör";
      Console.WriteLine("Yeni adres: "+Path.Combine(adres,adres2));
      Console.WriteLine("Klasör: "+Path.GetDirectoryName(adres));
      Console.WriteLine("Dosya adı: "+Path.GetFileName(adres));
      Console.WriteLine("Uzantısız dosya adı: "+Path.GetFileNameWithoutExtension(adres));
      Console.WriteLine("Tam adres: "+Path.GetFullPath(adres));
      Console.WriteLine("Kök dizin: "+Path.GetPathRoot(adres));
      Console.WriteLine("Geçici dosya adı: "+Path.GetTempFileName());
      Console.WriteLine("Geçici dosya dizini: "+Path.GetTempPath());
      Console.WriteLine("Dosya uzantısı var mı? "+Path.HasExtension(adres));
      Console.WriteLine("Alt dizin ayıracı: "+Path.AltDirectorySeparatorChar);
      Console.WriteLine("Dizin ayıracı: "+Path.DirectorySeparatorChar);
      Console.Write("Geçersiz dosya adı karakterleri: ");
      char[] dizi=Path.GetInvalidFileNameChars();
      foreach(char b in dizi)
         Console.Write(b+" ");
      Console.Write("\nGeçersiz adres karakterleri: ");
      char[] dizi2=Path.GetInvalidPathChars();
      foreach(char b in dizi)
         Console.Write(b+" ");
      Console.WriteLine("\nAdres ayırıcı karakter: "+Path.PathSeparator);
      Console.WriteLine("Kök dizin ayıracı: "+Path.VolumeSeparatorChar);
   }
}

Dosya yazma ve okuma işlemleri

değiştir

FileStream sınıfı

değiştir

FileStream sınıfı ile diskteki bir dosya açılır. StreamReader ve StreamWriter sınıflarıyla üzerinde işlem yapılır. Dosyalar üzerinde metin tabanlı ve bayt tabanlı işler yapabiliriz. Bir FileStream nesnesi çok değişik yollarla oluşturulabilir. Örnekler:

string adres=@"C:\Program Files\deneme.txt";
FileStream FSnesnesi1=new FileStream(adres,FileMode.OpenOrCreate);
FileStream FSnesnesi2=new FileStream(adres,FileMode.OpenOrCreate,FileAccess.Write);
FileStream FSnesnesi3=new FileStream(adres,FileMode.OpenOrCreate,FileAccess.Write,FileShare.None);
FileInfo FInesnesi1=new FileInfo(adres);
FileStream FSnesnesi4=FInesnesi1.OpenRead();
FileInfo FInesnesi2=new FileInfo(adres);
FileStream FSnesnesi5=FInesnesi2.OpenWrite();
FileInfo FInesnesi3=new FileInfo(adres);
FileStream FSnesnesi6=FInesnesi3.Create();
FileInfo FInesnesi4=new FileInfo(adres);
FileStream FSnesnesi7=FInesnesi4.Open(FileMode.OpenOrCreate);

Bu nesne yaratımlarındaki FileMode, FileAccess ve FileShare enumlarını önceden görmüştük. Dosyayla ilgili işlemimiz bittiğinde FileStream sınıfının Close() metodu ile FileStream nesnesi tarafından tutulan kaynaklar boşaltılır ve dosyayı başka prosesler kullanabilir hâle gelir. Close() metodunun kullanılışı:

FSnesnesi1.Close();

FileStream sınıfı ile yazma ve okuma

değiştir

FileStream sınıfının Read() ve ReadByte() metotları dosya akımından byte düzeyinde veri okumamızı sağlarlar. ReadByte() metodu akımdan okuma yapamadığı zaman geriye -1 değerini döndürür. ReadByte() metodunun prototipi:

int ReadByte()

Bu metot ile akımdan bir baytlık bilgi okunur ve akımdaki okuma pozisyonu bir artırılır ki tekrar okuma da aynı değer okunmasın. Okunan byte değeri inte dönüştürülüp int olarak tutulur. İkinci metodumuz ise:

int Read(byte[] dizi, int baslangic, int adet)

Bu metot ile adet kadar bayt akımdan okunur, okunan bu baytlar dizi dizisine baslangic indeksinden itibaren yerleştirilir. Geri dönüş değeri okunan byte sayısıdır. Şimdi komut satırı argümanı olarak adı alınan dosyanın içeriğini ekrana yazan bir program yazalım:

using System;
using System.IO;
class DosyaAkimi
{
   static void Main(string[] args)
   {
      string adres=args[0];
      FileStream fs=new FileStream(adres,FileMode.Open);
      int OkunanByte;
      while((OkunanByte=fs.ReadByte())!=-1)
         Console.Write((char)OkunanByte);
   }
}

Şimdi de bir dosyaya byte düzeyinde veri yazmak için kullanılan Write() ve WriteByte() metotlarını inceleyelim. Bir dosya akımına bir byte yazmak için

void WriteByte(byte veri)

metodu kullanılır. Eğer yazma işlemi başarısız olursa çalışma zamanı hatası oluşur. Dosya akımına bir bayt dizisi yazdırmak içinse

void Write(byte[] dizi,int baslangic,int adet)

metodu kullanılır. Bu metot ile byte dizisinin baslangic indeksinden itibaren adet kadar elemanı akıma yazılır. Akımın konum göstericisi yazılan byte kadar ötelenir.

Dosya akımına yazılan veriler dosya sistemindeki dosyaya hemen aktarılmaz. Dosya akımı tamponlama mekanizması ile çalıştığı için belirli bir miktar veri yazılana kadar dosya güncellenmez. Ancak FileStream sınıfının Flush() metodunu kullanarak istediğimiz anda tamponu boşaltıp dosyayı tampondaki bilgilerle güncelleyebiliriz. Şimdi bir örnek program yazalım. Programımız kullanıcının girdiği yazıları (Console.ReadLine() ile) bir txt dosyasına kaydetsin, dosyanın adı da komut satırı argümanı olarak verilsin.

using System;
using System.IO;
class deneme
{
   static void Main(string[] args)
   {
      string dosya=args[0];
      FileStream d=new FileStream(dosya,FileMode.CreateNew,FileAccess.Write);
      Console.Write("Dosyanın içeriğini yazın: ");
      string icerik=Console.ReadLine();
      foreach(char a in icerik)
         d.WriteByte((byte)a);
      d.Flush();
   }
}

FileStream sınıfının önemli özellikleri:
bool CanRead Akımdan okuma yapılıp yapılamayacağı öğrenilir.
bool CanSeek Akımda konumlandırma yapılıp yapılamayacağı öğrenilir.
bool CanWrite Akıma yazma yapılıp yapılamayacağı öğrenilir.
long Position Akımdaki aktif konum bilgisi öğrenilir.
long Length Akımın bayt olarak büyüklüğü öğrenilir.

FileStream sınıfının önemli metotları:
void Lock(long pozisyon,long uzunluk) Bu metotla akımın pozisyondan itibaren uzunluk kadar alanı başka proseslerin erişimine kapatılır.
long Seek(long ofset,SeekOrigin a) Bu metotla akımın konumu SeekOrigin ile belirtilmiş konumdan ofset byte kadar ötelenir. SeekOrigin enumunun içerdiği sözcükler şunlardır:

  • Begin Akımın başlangıç noktası
  • Current Akımın o anda bulunduğu nokta
  • End Akımın en son noktası

StreamReader sınıfı

değiştir

StreamReader sınıfı FileStream sınıfının aksine baytlarla değil, metinlerle ilgilenir. Bir StreamReader nesnesinin oluşturulma yöntemleri:

string dosya=@"C:\deneme\ornek.txt";
FileStream fs=new FileStream(dosya,FileMode.Open);
StreamReader sr1=new StreamReader(fs);
StreamReader sr2=new StreamReader(dosya);
FileInfo fi=new FileInfo(dosya);
StreamReader sr3=new StreamReader(fi);

Diğer sınıflarda olduğu gibi StreamReader nesneleriyle işimiz bittiğinde Close() metodunu kullanarak kaynakların iade edilmesi tavsiye edilir. StreamReader sınıfının önemli metotları:

string ReadLine()

Akımdan bir satırlık veriyi okur ve string olarak tutar. Eğer veri okunamazsa null değeri tutar. Okunan satırın sonuna "\n" eklenmez.

string ReadToEnd()

Akımdaki verilerin tamamını string olarak tutar. Okuma işlemi aktif konumdan başlayacaktır. Eğer okuma yapılamazsa boşluk tutar.

int Read()

Akımdan bir karakterlik bilgi okunur ve int'e dönüştürülür. İşlem başarısız olursa -1 ile geri döner.

int Read(char[] dizi,int indeks,int adet)

Akımdan adet kadar karakteri dizi[indeks] elemanından itibaren diziye yerleştirir. Yerleştirilen karakter sayısını döndürür.

int Peek()

Akımdan bir karakterlik bilgi okunur ve bu karakterin inte dönüşmüş hâli ile geri dönülür. İşlem başarısız olursa -1 ile geri döner. En önemli nokta ise konum göstericisinin yerinin değiştirilmemesidir.

Şimdi bir text dosyasının nasıl satır satır okunabileceğini görmek için bir örnek yapalım. Şimdi bir txt dosyası oluşturun ve içine şunları yazın: (adı deneme.txt olsun)

Bu bir metin belgesidir.
Bu deneme amaçlı yazılmıştır.
--------------------
Vikikitap

Şimdi programımızı yazalım:

using System;
using System.IO;
class Deneme
{
   static void Main()
   {
      string dosya="deneme.txt";
      FileStream fs=new FileStream(dosya,FileMode.Open);
      StreamReader sr=new StreamReader(fs);
      string satir;
      while((satir=sr.ReadLine())!=null)
         Console.WriteLine(satir);
      fs.Close();
    }
}

StreamWriter sınıfı

değiştir

StreamReader sınıfı ile dosyalardan text tabanlı veriler okunabiliyordu. StreamWriter sınıfı ise bunun tam tersini yapar. Yani StreamWriter sınıfı ile dosyalara text tabanlı veriler yazılır. Bir StreamWriter nesnesi şu yollarla oluşturulabilir:

string dosya=@"C:\dosya.txt";
FileStream fs=new FileStream(dosya,FileMode.Open);
StreamWriter sw1=new StreamWriter(fs);
StreamWriter sw2=new StreamWriter(dosya);
FileInfo fi=new FileInfo(dosya);
StreamWriter sw3=fi.CreateText();

StreamReader sınıfında olduğu gibi StreamWriter sınıfında da Close() metoduyla StreamWriter nesnesine ilişkin kaynaklar iade edilir. StreamWriter sınıfının en önemli metotları:

void Write(string str)

Bu metotla akıma str yazısı eklenir. Yazının sonuna herhangi bir sonlandırıcı karakter konmaz. Bu metot ile diğer bütün veri türlerinden veri eklemek mümkündür. Örneğin: Write(5), Write(true), Write('c')

void WriteLine(string str)

Write metoduyla aynı işi yapar. Tek fark eklenen yazının sonuna kendisi "\n" stringini koyar. Ayrıca Write metodundan farklı olarak WriteLine() metodunu parametresiz kullanabiliriz. Bu durumda akıma sadece "\n" eklenir.

void Flush()

Tampondaki bilgilerin boşaltılmasını ve dosyanın güncellenmesini sağlar.

Ayrıca StreamWriter sınıfının NewLine özelliği ile satır ayıracı olan karakterleri belirleyebiliriz. Varsayılan olarak bu karakter "\n" ve "\r"dir. StreamWriter sınıfının kullanımına bir örnek verelim. Örneğimiz kullanıcının -Console.ReadLine() ile- girdiği yazıları dosyaya kaydetsin. Dosyanın adı komut satırı argümanıyla belirlensin.

using System;
using System.IO;
class Deneme
{
   static void Main(string[] args)
   {
      string dosya=args[0];
      FileStream fs=new FileStream(dosya,FileMode.Append,FileAccess.Write);
      StreamWriter sw=new StreamWriter(fs);
      Console.Write("Yazınızı girin: ");
      string yazi=Console.ReadLine();
      sw.Write(yazi);
      sw.Flush();
   }
}

BinaryWriter ve BinaryReader sınıfları

değiştir

BinaryWriter ve BinaryReader sınıflarının yaptığı iş StreamReader ve StreamWriter sınıflarının yaptığı işin aynısıdır. Ancak BinaryWriter ve BinaryReader sınıflarıyla StreamReader ve StreamWriter sınıflarından farklı olarak her türde veriyi akıma yazdırabiliriz, yani verinin illaki string olma zorunluluğu yoktur. Bu sınıflarda sırasıyla Write(int), Write(char), Write(char[]), Write(byte) ve ReadByte(), ReadChar(), ReadUInt32, ReadString() vb. metotlar bulunmaktadır. Bu metotlar bütün temel veri türleri için bildirilmiştir. Şimdi bir örnek program yazalım. Programla önce çeşitli türlerde verileri bir dosyaya yazalım, sonra bu verileri tekrar okuyalım.

using System;
using System.IO;
class Deneme
{
   static void Main()
   {
      int i=5;
      decimal d=15.54M;
      char c='A';
      string dosya="deneme.txt";
      FileStream fs1=new FileStream(dosya,FileMode.OpenOrCreate);
      BinaryWriter bw=new BinaryWriter(fs1);
      bw.Write(i);
      bw.Write(d);
      bw.Write(c);
      bw.Close();
      FileStream fs2=new FileStream(dosya,FileMode.Open);
      BinaryReader br=new BinaryReader(fs2);
      Console.WriteLine(br.ReadInt32());
      Console.WriteLine(br.ReadDecimal());
      Console.WriteLine(br.ReadChar());
      br.Close();
    }
}

NOT: BinaryWriter sınıfıyla oluşturulan bir dosyayı Notepad ile okumaya kalkarsanız anlamsız simgelerle karşılaşırsınız. Çünkü BinaryWriter sınıfı dosyalara text yöntemiyle değil, binary yöntemle kayıt yapar. BinaryReader sınıfı da bu binary kayıtları okur.

Console I/O işlemleri

değiştir

I/O işlemleri için gerekli olan sınıflardan System.IO isim alanında olmayan tek sınıf Console sınıfıdır. Şimdiye kadar Console sınıfını ekrana bir şeyler yazmak için ya da kullanıcıdan girdi almak için sıklıkla kullandık. Şimdi ise Console sınıfının daha birçok yönünü göreceğiz.

Konsol I/O işlemleri için önceden tanımlanmış üç tane standart akım mevcuttur. Bu akımlar TextWriter türü olan Console.Out, Console.Error ve TextReader türünden olan Console.In'dir. Konsol ekranına yazdığımız yazılar aslında TextWriter sınıfının metotları ile olmaktadır. Console.WriteLine ise bizim için sadece bir aracılık görevi yapar. Örneğin aşağıdaki her iki satır da eş görevdedir. İkisi de ekrana merhaba yazar.

Console.Out.WriteLine("merhaba");
Console.WriteLine("merhaba");

Yani özetle Out, Console sınıfına bağlı bir özelliktir ve geri dönüş tipi TextWriter'dır ve bu veriyle TextWriter sınıfının static olmayan bir metodu olan WriteLine()'a erişiriz. Örneğin aşağıdaki kod da mümkündür:

TextReader tr=Console.In;
string s=tr.ReadLine();
TextWriter tw=Console.Out;
tw.WriteLine(s);

Yukarıdaki kod önce kullanıcıdan girdi alır, sonra aldığı bu girdiyi ekrana verir. TextReader ve TextWriter System.IO isim alanında bulunan sınıflardır.

Konsol ekranına yazı yazdırmak için Console sınıfının WriteLine() ve Write() metotlarını kullanırız. Bu ikisi arasındaki tek fark WriteLine'ın yazının sonuna "\n" ekleyip, Write'ın eklememesidir.

Konsoldan bilgi almak için Read() ve ReadLine() metotlarını kullanırız. Eğer tamponda herhangi bir veri yoksa Read() metodu kullanıcıdan veri girişi ister ve girilen stringteki ilk karakteri int olarak tutar. Sonraki Read() metotları ise o stringteki diğer karakterleri tutar. Eğer veri okunamazsa -1 değeri tutar. Örnek:

Console.Write((char)Console.Read()+" "+(char)Console.Read()+" "+(char)Console.Read());

Bu satırda önce kullanıcıdan veri girişi istenir. Diyelim ki kullanıcı deneme girmiş olsun. Bu durumda ekrana

d e n

yazılır. ReadLine() metodu Read() metodunun aksine ekrandan girdileri string olarak alır. Console.In özelliğini kullanarak da Read() ve ReadLine() metotlarını çağırabiliriz. Ayrıca Console.Out özelliğini kullanarak da Write() ve WriteLine() metotlarını kullanabiliriz. Console.In'den erişebileceğimiz yani TextReader sınıfının diğer metotları:

int Peek()

Bu metot ile standart girdi akımından bir karakter okunur ancak bu karakter tampondan silinmez. Örnek:

Console.Write((char)Console.In.Peek()+" "+(char)Console.In.Peek()+" "+(char)Console.In.Peek());

Burada kullanıcının ekrana deneme yazdığını varsayarsak ekrana d d d yazılacaktır.

int ReadBlock(char[] dizi,int indeks,int adet)

Bu metot ile standart girdi akımından adet kadar karakter diziye indeks elemanından itibaren yerleştirilir.

string ReadToEnd()

Bu metot ile standart girdi akımındaki bütün veriler okunarak tampondan temizlenir. Okunan veriler string nesnesi olarak döndürülür.

Standart akımların yönlendirilmesi

değiştir

C#'ta bütün I/O işlemleri akımlar (stream) üzerine kuruludur. Standart akımları başka akımlara yönlendirmek mümkündür. Örnek olarak komut satırında bir programı şöyle çalıştırırsak

programadi > deneme.txt

Bu programın, ekran çıktılarını deneme.txt dosyasına yazacağı anlamına gelir. Bu da standart çıktı olan konsolun başka akıma yönlendirilmesi anlamına gelir. Komut satırından

programadi < deneme.txt

Burada da Console.ReadLine() ya da Console.Read() yerine deneme.txt dosyasındaki metin kullanılır. C# programlarımız içinde akımları yönlendirmek içinse Console sınıfının şu metotları kullanılır.
static void SetOut(StreamWriter sw) veya static void SetOut(TextWriter tw)
static void SetError(StreamWriter sw) veya static void SetError(TextWriter tw)
static void SetIn(StreamReader sr) veya static void SetIn(StreamReader sr)
Şimdi Console.In akımını SetIn metodu ile bir dosya akımına yönlendirelim. Yani giriş klavyeden değil, dosyadan alınsın.

using System;
using System.IO;
class Deneme
{
   static void Main()
   {
      FileStream fs=new FileStream("deneme.txt",FileMode.Open);
      Console.SetIn(new StreamReader(fs));
      Console.WriteLine(Console.ReadLine());
      Console.WriteLine(Console.ReadLine());
   }
}

Programı derleyin, ancak çalıştırmadan önce programla aynı klasörde deneme.txt dosyası oluşturun ve içine iki satırlık yazı yazın. Aynı şekilde Console.WriteLine() metodu da dosyaya yönlendirilebilir. Tabii ki bunun için Console.SetOut metodu kullanılmalıdır. Programın içindeki hata mesajlarını ise SetError metodu ile bir dosyaya yazdırabiliriz. Örnek:

using System;
using System.IO;
class Deneme
{
   static void Main()
   {
      Console.WriteLine("Bu bir denemedir.");
      FileStream fs1 = new FileStream("deneme.txt", FileMode.Create);
      TextWriter tw = Console.Out;
      StreamWriter sw = new StreamWriter(fs1);
      Console.SetOut(sw);
      Console.WriteLine("Dosyaya yazma yapıyoruz.");
      Console.SetOut(tw);
      Console.WriteLine("Merhaba dünya");
      sw.Close();
   }
}

Burada önce ekrana Bu bir denemedir. yazılıyor. Sonra yeni bir FileStream nesnesi oluşturuluyor. Sonra hedefi konsol ekranı olan bir TextWriter nesnesi oluşturuluyor. Sonra ilişiği deneme.txt olan bir StreamWriter nesnesi oluşturuluyor. Sonra çıktı birimi deneme.txt olarak değiştiriliyor. Sonra ekrana -daha doğrusu dosyaya- Dosyaya yazma yapıyoruz. yazdırılıyor. Sonra çıktı birimi yeniden ekran yapılıyor. Sonra ekrana Merhaba dünya yazdırılıyor. En son da sw akımının kaynakları boşaltılıyor.

Bu kitabın diğer sayfaları
  • Sınıflar
  • Operatör aşırı yükleme
  • İndeksleyiciler
  • Yapılar
  • Enum sabitleri
  • İsim alanları
  • System isim alanı
  • Temel I/O işlemleri
  • Temel string işlemleri
  • Kalıtım
  • Arayüzler
  • Kısmi tipler ve metotlar
  • İstisnai durum yakalama mekanizması
  • Temsilciler
  • Olaylar
  • Önişlemci komutları
  • Göstericiler
  • Assembly kavramı
  • Yansıma
  • Nitelikler
  • Örnekler
  • Şablon tipler
  • Koleksiyonlar
  • yield
  • Veri tabanı işlemleri
  • XML işlemleri
  • Form tabanlı uygulamalar
  • Visual Studio.NET
  • Çok kanallı uygulamalar
  • ASP.NET