"Enter"a basıp içeriğe geçin

Dosya İşlemleri

 

Dosya İşlemleri

Dosyalama, elde ettiğimiz verileri hafızaya kaydetmektir. Yani bilgi depolarız. Dosya işlemleri sayesinde programımızın dosyaları kontrol etmelerini sağlayabiliriz. Aslında şimdiye kadar öğrendiğimiz cin ve cout’dan bi farkı yoktur. Zaten onlar da özel dosyalardır. Biz burada bu özel dosyalara yani bizim gördüğümüz şekliyle  siyah ekrana  değil de istediğimiz bir dosyaya okuma-yazmayı öğreneceğiz.

Dosya işlemleri için öncelikle <fstream> sınıfını eklemeliyiz. fstream sınıfı ile hem okuma hem yazma yapabiliriz. Eğer sadece okuma yazacaksak ifstream, sadece yazma yapacaksak ofstream kullanabiliriz.

Dosyalamanın 2 farklı türü vardır. Bunlar text dosyalama ve binary dosyalamadır:

text dosyaları sıralı erişim, binary dosyaları rastgele erişim yapar.
Yani text’de veriler ilk veriden sonra ard arda eklenir
Binary dosyalarda ise, veriler işletim sisteminde depolandıkları  şekilde tutulur
text dosyaları EOF ile biter. En baştan başlanarak EOF ye kadar işlem yapılır.Windows işletim sisteminde EOF ctrl-z ile konulabilir.
Text dosyalarında aynı anda okuma ve yazma yapılamazken binary dosyalarda yapılabilir.
Hız için binary, düşük boyut için text dosyalar kullanılır.

Okuma yazma yapmak için önce bir stream yani fstream sınıfından bir nesne oluşturmalıyız

Dosyaya yazdırma

öncelikle out modunda açmalıyız: dosya1.open(“deneme1.txt”, ios::out);
Dosya açıldıktan sonra, tıpkı ekrana yazı yazdırır gibi, dosya1<<“Dosyaya yaziyorum”; diyerek dosyaya yazdırabiliriz.
Eğer yazma modunu out olarak açarsak, dosyanın içeriğini tamamen silerek,  sıfırdan yazmaya başlar. Yani dosyanın önceki içeriğini kaybederiz.

Görüldüğü gibi önceki içerik silindi

 

Eğer dosyanın içeriğini kaybetmeden, sonuna eklemek istiyorsak, ios::app modunda açmalıyız. Böylece EOF karakterinden hemen önceden itibaren yazmaya başlar

bu modda  önceki içeriği silmedi

 

 

Dosyadan okuma

Bunun için in modunda açmalıyız: dosya1.open(“deneme1.txt”, ios::in); //bu modda dosya yoksa oluşturmaz
Aktaracağımız değişken string str1; olsun. Yine cin gibi, dosya1>>str1; dersek, text dosyasının başından başlayarak, gördüğü ilk boşluk, enter yada tab karakterine (whitespace karakterler) kadar okur.
Bu okumayı yaptıktan sonra, okuduğu yerin sonuna bir işaretçi bırakır. Böylece tekrar okumaya o noktadan başlar.
Okuyacağımız tip ile aktaracağımız tip uyumlu olmalı. Mesela eğer stringe aktaracaksak, string text dosyasındaki tüm tipleri kabul edebilir. Ama eğer bir integer’a aktaracaksak, text içindeki değer bir sayı olmalı.

İşlemleri boşluklara göre yaptığı için, boşlukları yazdırmadı

 

 

Bunun yerine
while(dosya1>>str1){
cout<<str1;
}

kullanabiliriz. Çünkü aslında >> işareti aşırı yüklenmiş bir fonksiyondur ve eğer işlem başarılı ise 1, başarısız ise 0 döner.
Okunacak birşey kalmadığında işlem başarısız olacağı için 0 döner ve döngüden çıkar.

Yazma modunda açarsak dosyaya başka program erişemez. Bu yüzden yazma modunda kalma süresini olabildiğince azaltmak mantıklıdır.

clear ve seekg  fonksiyonları: Sıralı erişimde sürekli ileri giderek EOF belirtecine ulaşıldığında, dosyanın en başına dönmek isteyebiliriz. Bunun 2 yolu vardır. Ya dosya açılıp kapatılır (fazladan maliyet), yada önce dosya1.clear(); fonksiyonu ile EOF durumu kaldırılır ve sonra dosya1.seekg(); diyerek imleç en başa getirilir. Böylece tekrar dosya açma maaliyeti olmadan en başa dönmüş oluruz.

Text formatında dosya işlemleri nasıl yapılır gördük, şimdi binary dosyalara geçelim

Binary Dosyalar

Şimdiye  kadar gördüklerimiz, text yani sıralı erişimli dosyalardı. Yani dosyanın herhangi bir yerine erişebilmek için, en baştan başlayarak istediğimiz  konuma kadar tüm dosyayı gezmemiz gerekiyordu ve bu gezme işlemleri boşluklara göre yapılıyordu. Ama bu bizim her zaman işimize yaramayabilir. Çünkü hedefe kadar gezmenin bir maliyeti vardır. Bunun yerine Binary dediğimiz ve rastgele erişime izin veren, yani dosyanın tamamını gezmeden istediğimiz yere erişebildiğimiz dosya tipi kullanılabilir. Bu dosya tipinin dezavantajı da, text dosyalara göre daha fazla yer kaplayabilmesidir.

Yani sonuç olarak hangi dosyalama tipini seçeceğimiz ihtiyacımıza bağlıdır. Eğer sürekli gezme işlemi yapacaksak ve depolama alanı önemli değilse binary kullanılabilir. Depolama kaygımız varsa text kullanılmalıdır.

Binary dosyaların nasıl işlediğine gelecek olursak, verileri işletim sisteminin tuttuğu şekilde tutar diyebiliriz. Yani aslında hafızada bloklar oluşturduk.

Eğer dosyamızda sadece integer değerler olduğunu biliyorsak, her sayı için 4 bayt ayrılıyor demektir.

Her bloğun 4 bayt tuttuğunu bildiğimiz için, ilk değişken 0-4 hafızaları arasında, ikinci değişken 4-8 hafızaları arasında diyebiliriz. Yani eğer pointer’ımızı 8. adrese getirip sonraki 4 baytlık veriyi bir int değişkene yazdır dersek, üçüncü sayıyı okumuş oluruz.

Aynı kullanım sınıf nesneleri için de geçerlidir.

Mesela kullanıcıların verilerini tutan bir binary dosyamız olsun. Her bir sınıf nesnesi yani kullanıcı için 100 byte yer ayıralım. Artık 0-100 konumları arasının 1. kullanıcıya, 100-200 arasının 2. Kullanıcıya ait verileri tuttuğundan emin olabiliriz. Böylece imlecin konumunu 700’e götürdüğümüzde, 8. Kullanıcıda olduğumuzu biliriz. Bu durum text file için geçerli değildi. Çünkü her bir kullanıcı kaydının eşit boyuttu olduğunu bilemeyiz.

Ör:

İlhan 150009  furkan 123 ahmet 532432 şeklinde isim ve numara tutan 3 kayıt olsun. Bu kayıtların her biri bir nesnedir. Text olarak yazdırırsak bu kayıtların boyutları farklı olur. 1. Kayıt 2.den büyüktür.  Bu yüzden mesela 12 karakter ileri git diyerek, sonraki kaydın başına erişeceğimizin garantisi yoktur. Text formatında olsaydı boşluklara göre işlem yapacaktık. Yani 3. Kayıt için 4. boşluktan sonrasına gidecektik gidecektik.

Ancak her bir kayıt için gerekenden fazla ve eşit miktarda yer ayırılsak (mesela 15) Her bir kayıt 15 yer tutar. İmleci başlangıç konumundan 15 ileri kaydırırsak, F harfine yani 2. Kaydın başına gelir.

Bunun avantajları ve dezavantajları vardır. Avantajı olarak, her kayda ulaşmak için en baştan başlayıp tüm dosyayı gezmemize gerek yoktur. Sadece pointerın yerini ayarlayarak istediğimiz elemana ulaşabiliriz. Dezavantajı ise, kayıt boş bile olsa 15 bayt tutar.

Ancak sayılar string yerine int olarak tutulduğundan, 8 basamaklı bir sayıyı 4 baytta tuttuğumuz için büyük sayılarda alandan tasarruf da sağlayabilir.

Binary-Text dosyaların avantajlarını-dezavantajlarını anladığımıza göre, binary dosyalarla işlemlerin nasıl yapıldığına bakalım.

Örnek binary dosya işlemleri

Daha önce okunacak şeyin string olması gerekmediği , herhangi bir veri tipini tutabileceğimizi göstermiştik. Sonuçta herşey byte’lardan oluşuyor ve bu verileri bloklar halinde okuyor. Burada binary dosyada bir string yada int gibi bir değer değil de, bir sınıfa ait nesneleri tutacağız.
Yani her nesne 40 byte ise 1-40 arası ilk kayıt,41-80 arası 2. kayıt gibi gidecek. Aslında bit bit okuyacağımız için dosyayı açtığımızda anlamı olmayan karakterlermiş gibi gözükecek, ama birleştirdiğinde bir nesne oluştuğu için anlamı olacak.

Öncelikle bilmemiz gereken 3 şey var.
Binary dosyalarda aynı anda okuma ve yazma işlemi yapabilmemiz için imleç görevi gören 2 tane pointer bulunuyor. Bunlardan biri okuma imleci, seekg(); ile ayarlanabilir. Diğeri de yazma imleci, seekp(); ile ayarlanabilir.
Binary dosyalarda << >> operatörleri kullanılmaz. Streamler konusunda da gördüğümüz write, read fonksiyonları kullanılır. Aşağıdaki örnekte bunların kullanımlarını göreceksiniz.

 

Aslında olan

 

 

Text dosyasını açtığımızda gözüken

 

Burada yazdığımız şey bir string yada başka bir veri türü değil, çok fazla bayttan oluşan bir nesne. Bu baytların tek başlarına herhangi bir anlamı yok. Anlamlı olabilmeleri için bir araya gelip bir nesne oluşturmaları lazım.
Bu yüzden eğer yazdığımız dosyayı açarsak anlamsız şekiller görürüz. Çünkü text programı bu normalde tek başlarına anlamı olmayan baytları stringe çevirmeye çalışır.
Yani aslında o anlamsız görülen şekiller birleşince ilhan 5 12432 oluyor

Mesela 5 bayttan oluşan bir nesnemiz olsun. 1110011001011100100101101101111001101101 olarak bir anlamı vardır. Böyle bütün haldeyken bir nesne oluşturur.
Ama tek tek baktığımızda

11100110
01011100
10010110
11011110
01101101

Bunlar tek başlarına birer karaktermiş gibi görünür. Ve text editörü bu karakter karşılıklarını göstermeye çalışır.

Yani text editörü bayt bayt bakarken, bizim yazdığımız program 5 bayt 5 bayt okuduğu için, binary dosyaları text editörleri ile okuyamayız.

    Bir cevap yazın

    E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir