Etiketler

Youtube Kanalıma Abone Olunuz

11 Ekim 2019 Cuma

QuickBasic Kursu: Bölüm 12: Dosya işlemleri-3

Önceki Bölüm: QuickBasic Kursu: Bölüm 11: Dosya İşlemleri-2
Güncelleme: 14 Ekim 2019
Yalnız metin içermeyen dosyalar vardır. Örneğin; resim(BMP,JPG,GIF ...) ses(WAV,MP3 ...), video(AVI, MOV, MPG ...) gibi dosyalar.

Bu tür dosyalar içinde metin aranmaz ve metinle ilgili işlemler de yapılmaz.
Ama örneğin bir GIF dosya yapısını öğrendiniz ve dosya içindeki resmi ekrana basmak istiyorsunuz.
Bunun için dosyayı binary olarak açıp içindeki kodları resim kodlarına dönüştürmelisiniz.

Çalışma sistemi RANDOM dosya gibidir ancak önceden bir kayıt yapısı belirleme gerekliliği yoktur.
GET ve PUT ile dosyanın istenilen kısmını okuyabilir, değişiklik yapabilirsiniz.

Binary(ikili) Dosya Oluşturma ve Yazma

OPEN "c:\ornek\ikili.bin" FOR BINARY AS #1
Random dosyada olduğu gibi dosya yoksa oluşturulur.
Varsa sorun çıkmaz.
Üstteki kodu denerseniz, dosya yok ise boş bir dosya oluşur.
A$ = "Mesut"
PUT #1, , A$
A$ değişkeni içeriğini PUT ile dosyaya yazdırdık.
Kayıt numarası belirtmedik.
Öncesinde dosyaya herhangi bir okuma veya yazma işlemi yapılmadığı için ilk 5 byte yazdırılır.
A$ = CHR$(13) + CHR$(10) + "Akcan"
PUT #1, , A$
İkinci satır oluşturuluyor.
Sıralı erişimli dosyada satır atlamak için ikinci bir PRINT komutu kullanılıyordu ama burada byte byte işlem yapıldığı için satır atlama kodlarını da bizim girmemiz gerekir.
CHR$(13) + CHR$(10) dan oluşan iki karakter sonraki satıra atlamayı sağlar.
ENTER tuşunun yaptığını yapar.

Üstteki kodları deneyip dosya içeriğini inceleyin sonra aşağıdaki kodları deneyin.
Burada kayıt yeri olarak 2 yazılı.
Değişken içeriği dosyanın 2. baytından başlayarak doldurulur.

Tabii ki o kısımdaki eski bilgiler değişmiş olur.
PUT #1, 2, A$
CLOSE

Binary Dosya Okuma

Dosyadan byte byte bilgi okumak için GET komutu kullanılır.
GET # dosyano, bytekonum, değişken
şeklinde kullanılır. Konum belirtilmezse PUT komutunda olduğu gibidir.

Binary dosyalarda çalışırken byte olarak okuduğumuz verilerden bir kısmı sayı içeriyor olabilir.
Örneğin bir resim dosyasında ilk 3 bayt resim türünü, sonraki 2 byte renk derinliğini, sonraki 15 byte tanımlama vs.. olabilir.

Bunları tek tek GET komutuyla diskten okutmak yerine gerekli bilgi bir seferde bir STRING değişkene atanır.
MID$ ile gerekli bytelar değişkenden alınır.

Fakat sayısal değerler byte'a dönüştüğünde farklı string değerlere sahip olur.
Bir önceki derste dosyayı HexViewer ile incelediğimizde görmüştük.
Bu tür bilgileri dönüştürmek için QBASIC içindeki hazır fonksiyonlar kullanılır.

STRING'İ SAYIYA DÖNÜŞTÜRME

CVI: (ConVert to Integer) 2 byte'lık String'i Integer sayı değerine dönüştürür. Örneğin
PRINT CVI("[x") 'Sonuç : 30811
CVS: (Convert to Single) 4 byte'lık String'i Single sayı değerine dönüştürür.
PRINT CVS("AbCd") 'Sonuç : 1.441678E+22
CVL: (Convert to Long) 4 byte'lık String'i Long sayı değerine dönüştürür.
PRINT CVL("AbCd") 'Sonuç : 1682137665
CVD: (Convert to Double) 8 byte'lık String'i Double sayı değerine dönüştürür.
PRINT CVD("Mesut.Akcan")
 'Sonuç : 4.412931560721696D+208
 'İlk 8 karakteri dönüştürdü

SAYIYI STRING'E DÖNÜŞTÜRME

MKx$ komutları CVx komutlarının tersini yapar.

MKI$: (MaKe Integer to $tring) Integer sayı değerini 2 baytlık(karakter) String'e dönüştürür.
Örneğin:
PRINT MKI$(30811) 'Sonuç: [x

MKS$: Single sayı değerini 4 baytlık String'e dönüştürür.

MKL$: Long sayı değerini 4 baytlık String'e dönüştürür.

MKD$: Double sayı değerini 8 baytlık String'e dönüştürür.

Okuma ya da yazma konumu

LOC fonksiyonu ile yazılacak ya da okunacak kayıt numarası öğrenilir.
Binary dosyada byte olarak konumu, random dosyada ise kayıt numarasını verir.

OPEN "c:\ornek\test.txt" FOR BINARY AS #1
a$ = MKI$(5214)
PUT #1, 8, a$
PRINT LOC(1)
CLOSE

UYGULAMA

BMP formatında bir resim bulun ve c:\ornek klasörüne kopyalayın.
Dosyanın adını resim.bmp olarak değiştirin. Aşağıdaki kodları yazıp çalıştırın.
Bu uygulama resim dosyanız hakkında bazı bilgileri ekrana yazacaktır.
BMP dosya yapısı hakkında daha detaylı bilgi
CLS
dosya$ = "c:\ornek\resim.bmp"
OPEN dosya$ FOR BINARY AS #1
'PRINT "Dosya boyutu : "; LOF(1)
baslik$ = SPACE$(14)
boyut$ = SPACE$(4)
GET #1, 1, baslik$
GET #1, 15, boyut$
bmptur = CVI(boyut$)
IF bmptur = 40 THEN ' 12 ise OS/2 BMP
 baslikbilgi$ = SPACE$(40)
 GET #1, 15, baslikbilgi$
 renkd = CVI(MID$(baslikbilgi$, 15, 4))
ELSE
 PRINT "Windows BMP resim dosyası değil"
 END
END IF
dosyag = CVL(MID$(baslik$, 3, 4))
PRINT "Dosya Genişliği:"; dosyag; "byte"
PRINT "Renk Derinliği :"; renkd; "bit"
baslgen& = CVL(MID$(baslikbilgi$, 1, 4))
resGenislik = CVL(MID$(baslikbilgi$, 5, 4))
PRINT "Genişlik: "; resGenislik
resYukseklik = CVL(MID$(baslikbilgi$, 9, 4))
PRINT "Yükseklik: "; resYukseklik
PRINT
IF bmptur = 40 THEN
 PRINT "Sıkıştırma: ";
 skstrma = CVL(MID$(baslikbilgi$, 17, 4))
 IF skstrma = 0 THEN PRINT "Yok"
 IF skstrma = 1 THEN PRINT "8 Bit"
 IF skstrma = 2 THEN PRINT "4 Bit"
 kullRenk = CVL(MID$(baslikbilgi$, 33, 4))  
 PRINT "Kullanılan renk sayısı:"; kullRenk
END IF
CLOSE

Dosyayı Silme

DOS komut satırında bir dosyayı silmek için DEL komutu kullanılır.
Ama Qbasic içinden dosyası silmek istersek ne olacak?

Qbasic içinde de dosya silmek için bir komut var ama DEL değil KILL(öldür)
Kullanımı:
KILL "sürücü:\dosyayolu\dosyaadı"
Örnek:
KILL "c:\ornek\resim.bmp"
Dikkat ! Bu şekilde sildiğiniz dosyaya özel programlar kullanmadan ulaşmanız mümkün değildir.

Dosya adını değiştirme

NAME komutu ile dosya adı değiştirilebilir.
NAME "test.txt" AS "veri.dat"

Konum değiştirme

Dos komut satırında CD ile bulunduğunuz klasörü öğrenebilir ve konumu değiştirebilirsiniz.
Aktif klasörden başka bir klasöre geçiş yapmak için Qbasicde CHDIR komutu kullanılır.
Sürücü ve yol belirtilir
CHDIR "D:\PROGRAMLAR"

Klasördeki Dosyaların Listesi

DOS'da belirtilen klasördeki dosyaların listesini DIR ile alırız.
Qbasicde ise FILES komutu kullanılır.
Kullanımı:
FILES dosya türü tanımı
FILES ' bulunduğun klasörde tüm dosyalar
FILES "*.bmp" ' BMP resim dosyaları
FILES "c:\ornek\*.txt" ' belirtilen klasörde txt dosyalar
FILES "?.B*" ' Dosya adı tek harfli, uzantısı B ile başlayan dosyalar.

Yeni Klasör Oluşturma

Dos'da MKDIR ya da MD komutu ile klasör oluşturulur.
Qbasicde ise MKDIR ile
MKDIR "C:\ORNEK"
Eğer klasör yoksa yeni bir tane oluşur.
Klasör varsa Path/File access error hatası belirir.

Klasörü Silme

Dos'da RMDIR ya da RD ile klasör silinir.
Qbasicde ise RMDIR ile klasör silinir.
RMDIR "C:\ORNEK"
Klasör içeriği boş değilse Path/File access error hatası belirir. Klasörü silmek için önce içindekileri silmek gerekir.
KILL "C:\ORNEK\*.*"
RMDIR "C:\ORNEK"

Dosya Kopyalama

Qbasicde dosya kopyalamak için bir komut yoktur.
Kısayoldan SHELL komutu ile tüm dos komutlarını kullanabiliriz ama Shell komutu kullanmadan dosyayı nasıl kopyalarız?

Örnek kodlar aşağıda. Çok büyük dosyalarda bu kodlar sorun çıkarır.
Büyük dosyalar için ek kodlar gerekir. Bu sorunu çözmek de size ödev olsun :)
OPEN "c:\ornek\ikili.bin" FOR BINARY AS #1
g& = LOF(1) : a$ = SPACE$(g&)
GET #1, , a$
CLOSE
OPEN "c:\ornek\kopya.bin" FOR BINARY AS #1
PUT #1, , a$
CLOSE
PRINT "Dosya kopyalandı"

Hiç yorum yok:

Yorum Gönder