Quick Basic – Bölüm 12

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

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, 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. Herhangi bir okuma veya yazma 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 da 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
CVI : 2 byte’lık String’i Integer sayı değerine dönüştürür. Örneğin
PRINT CVI(“[x”) –> Sonuç : 30811

CVS : 4 byte’lık String’i Single sayı değerine dönüştürür.
CVL : 4 byte’lık String’i Long sayı değerine dönüştürür.
CVD : 8 byte’lık String’i Double sayı değerine dönüştürür.

SAYIYI STRING’E
MKI$ : Integer sayı değerini String’e dönüştürür. Örneğin
PRINT MKI$(30811) –> Sonuç : [x

MKS$ : Single sayı değerini String’e dönüştürür.
MKL$ : Long sayı değerini String’e dönüştürür.
MKD$ : Double sayı değerini 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.

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 "Run Length - 8 Bits"
	IF skstrma = 2 THEN PRINT "Run Length - 4 Bits"
	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ürmek) Kullanımı:

KILL “sürücü:\dosyayolu\dosyaadı”

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ü öğrenebilirsiniz. Bu klasörden başka 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.

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

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ı"