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