Aytaç Kalıncı – Perl Dosya İşlemleri

Dosya giriş çıkış fonksiyonları

 

Temel giriş çıkış fonksiyonları open, close, print, printf, write  fonksiyonlarıdır.

Bunları görmüştük . Hatırlayalım ve biraz daha inceleyelim.

 

Open Fonksiyonu : Dosya erişimi sağlar.

 

open (DOSYAM, “/u/ertan/dosya.txt”);

 

open, default olarak okuma amaçlı dosya açar.İlk defa açılan dosyaya yazmak için > kullanılır.

 

open (DOSYAM, “>/u/ertan/dosya.txt”);

 

Mevcut dosyaya eklemek için ise >> kullanılır;

 

open (DOSYAM, “>>/u/ertan/dosya.txt”);

Ayrıca

open (MAIL, “|mail ertan”);

 

şeklinde pipe ile kullanımını da görmüştük.

 

open fonksiyonu bunlardan başka daha birkaç çeşit dosya açma biçimi kullanır.

Aşağıdaki kullanım bunlardan birisidir.

 

open (CAT, “cat dosya*|”);

 

burada open, unix’teki  cat dosya* komutunu icra eder. | işareti dosya adından sonra yazılır. Buradaki komutla adı dosya ile başlayan tüm dosya isimleri bir dosyaya listelenir. Bu dosya bir giriş dosyası

gibidir ve CAT dosya değişkeni kullanılarak erişilebilir.

 

Örnek : pipe’lı komutla unix’teki w komutu çıktısını giriş olarak alma

 

Not: w komutu çıktısını aşağıda görüyorsunuz.Programı ona göre inceleyiniz.

ertan> w

 

11:09am  up 30 days,  2:31,  3 users,  load average: 0.06, 0.07, 0.01

 

USER      TTY      FROM                   LOGIN@    IDLE     JCPU   PCPU   WHAT

ftpadmin  ttyp3    darkness.anadolu  Wed 1pm  12:22m  0.12s  0.12s   -bash

poyraz     ttyp4    192.168.100.59      8:56am    0.00s     0.58s  0.07s   pine

ertan       ttyp0    192.168.100.9       9:52am    0.00s      0.29s  0.02s   w

 

 

1:  #!/usr/local/bin/perl

2:  # w çıktısından saat ve o an için bağlı olan kullanıcıları alalım

3:  open (WOUT, “w|”);       # w komutu çıktısı WOUT tarafından alınır

4:  $saat = <WOUT>;         # WOUT ‘ un ilk satırını okur(yani aşağıdaki satır)

#(11:09am  up 30 days,  2:31,  3 users,  load average: 0.06, 0.07, 0.01)

5:  $saat =~ s/^ *//;        #baştaki boşlukları çıkarır

6:  $saat =~ s/ .*//;          # ilk kelimeden sonraki her şeyi çıkartır(sondaki newline hariç).

#Kısaca 5. ve  6. satırlar saat’i(11:09am) elde eder.

$saat =~ s/pm|am$//;  #Not: sondaki -am- veya -pm- gösterimini kaldırmak istersek bu satırı ekleriz.

7:  <WOUT>;

#WOUT dan ikinci satırı okur bu satır bizim için gereksizdir. Aşağıdaki Başlık satırını atlat(geç) işlevi gerçekleşir.

#[USER   TTY   FROM     LOGIN@   IDLE   JCPU   PCPU   WHAT]

8:  @kullanicilar = <WOUT>;   #kalan satırlar @kullanicilar dizisine okunur.

9:  close (WOUT);  #WOUT dosyasıyla işimiz bitti.Sistem kaynaklarını tüketmemek için kapattık.

10: foreach $kullanicilar  (@kullanicilar) {#@kullanicilar’ın her bir elemanı, kullanıcı bilgisinin 1 satırını içerir.

11: $kullanicilar =~ s/ .*//; # programımız, bu satırın ilk kelimesine(kullanıcı adı) ihtiyaç duyar# .Bu yüzden 10,11 ve

12: }              #12 satırlarda döngü tamamlanınca newline hariç her şey temizlenir dizide sadece kullanıcı listesi bulunur.

13: print (“Saat:  $saat “);

14: print (“Halen bagli olan  kullanicilar:\n”);

15: $oncekikullanici = “”;

16: foreach $kullanici (sort @kullanicilar) {  #kullanıcılar alfabetik sıralanıyor

17:   if ($kullanici ne $oncekikullanici) ##Birden fazla aynı kullanici bağlantısı varsa, $oncekikullanici son basılan

#kullanici adını tutar. Ve $kullanici içindeki değer, $oncekikullanici ile aynı ise basılmaz

18:      print (“\t$kullanici”);      # ve uygun ise basılır

19:     $oncekikullanici = $kullanici;

20:         }

21: }

 

çalışması;    ertan> ./program.pl

 

Saat:  11:24

Halen bagli olan  kullanicilar:

ertan

ftpadmin

poyraz

 

 

DOSYADAN DOSYAYA YÖNLENDİRME

 

Unix’ te standart error ve standart çıktıyı aynı dosyaya yönlendirir.

sh komutu olarak şöyle yazılır.

 

$ program >dosya1 2>&1

 

Aşağıdaki program standart çıktı ve standart error dosyalarının yönlendirilişiyle ilgili bir örnektir.

 

Örnek :

#!/usr/local/bin/perl

open (STDOUT, “>Yazdir“) || die (“STDOUT dosya acma hatasi”);                 

open (STDERR, “>&STDOUT”) || die (“STDERR dosya acma hatasi”);            

print STDOUT (“Satir 1\n”);        

print STDERR (“Satir 2\n”);       

close (STDOUT); 

close (STDERR); 

 

çalışması; programın ekrana çıktısı yoktur.Çıktı Yazdir isimli dosyayadır.

 

Yazdir isimli çıktı dosyasının  içeriği şöyledir.

Satir 2

Satir 1

Sıralı yazmadığını gördük çünkü işletim sisteminin özelliğinden dolayı değerler buffer’ dadır ve buradan

önce STDERR ‘ e yazar. Bu problemi çözmek istersek dosya için buffer’ ı kullanmama işlemi yapılır.

Önce select ile dosya seçilir. Sonra $| sistem değişkenine 1 atanır.

Eğer $| değişkenine 0 olmayan değer atanırsa buffer kullanılmaz.

Tıpkı $~ ve $^ gibi $| da son kullanılan dosyaya etkilidir ki o dosya select ile son seçilendir.

Eğer  select kullanılmamışsa STDOUT’dur.

 

Şimdi $| kullanarak önceki örnekten farklı olarak sırayla yazan programı görelim.

 

Örnek :

 

#!/usr/local/bin/perl

open (STDOUT, “>Yazdir”) || die (“STDOUT dosya acma hatasi”);

open (STDERR, “>&STDOUT”) || die (“STDERR dosya acma hatasi”);

select (STDOUT);

$| = 1; #buffer’ı kapat.Seçilen dosya yazdırma kanalını aç,seçilen dosya  bir önceki satırda belirlendi:STDOUT.

# Not: Aslında STDOUT default dosya olduğundan onu select ile seçmeye gerek yoktu sadece $| = 1; yeterliydi.

print STDOUT (“Satir 1\n”);

print STDERR (“Satir 2\n”);

close (STDOUT);

close (STDERR);

 

Yazdir  dosyası içeriği aşağıdaki gibidir.

Satir 1

Satir 2

 

 

OKUMA VE YAZMA ERİŞİMİ TANIMLAMA

 

Okuma ve yazma erişimi ile dosyayı açmak için dosya adından önce +> kodlanır.

 

open (OKUYAZ, “+>dosya.dat”);

 

bu erişimle dosyanın bir kısmının üzerine yazma hakkı almış olursunuz. Bu tip kullanımlarda en verimli çalışma seek ve tell fonksiyonlari ile birlikte gerçekleştirilir.

Bunlar dosyada karakter(ler) atlama işlevi sağlar. İlerde inceleyeceğiz.

 

Not : ayrıca +<  eki’ de  okuma ve yazma amaçlı tanımda kullanılabilirler.

 

open (OKUYAZ, “+<dosya.dat”);

 

<  eki  okuma amaçlı tanımdır bu demektir ki aşağıdaki iki örnek aynıdır.

 

open (OKU, “<dosya.dat”);

open (OKU, “dosya.dat”);

 

 

close Fonksiyonu : dosya kapatır. Eğer | ile komut şeklinde kullanıldıysa (open (DOSYA, “cat dosya*|”); ) gibi O takdirde komut bitene kadar program bekler.

 

print, printf, write Fonksiyonu :  Bunları görmüştük.

 

select Fonksiyonu : Bir dosyayı default yapmak için kullanılır. Bunu da görmüştük.

 

eof Fonksiyonu : Dosya sonunu kontrol eder. Okunacak kayıt kalmamışsa 0 olmayan değer döndürür. Eğer okunacak kayıt varsa 0 döndürür. <> işaretlerinden etkilenir.  eof and eof() farklıdır.

eof nin <> işaretlerden nasıl etkilendiği görülür. Aşağıdaki örnekte bu durumu gözleyebiliriz.

Örnek programda  komut satırından isimleri verilen dosyalar(1 veya daha çok)’ın içeriği basılır.

 

dosya1 içeriği şöyle olsun;

Bu ilk dosyanın ilk satırı

Bu ilk dosyanın ikinci satırı

 

Dosya2 içeriği ise ;

Bu ikinci dosyanın ilk satırı

Bu ikinci dosyanın ikinci satırı

 

Örnek : eof ve <> birlikte kullanımı;

#!/usr/local/bin/perl

while ($kayit = <>) {#<>operatörü der ki; adları komut satırında verilen dosyalardan ,okunmakta olanın sıradaki satırını oku

print ($kayit);    # ve yazdır.

if (eof) {           #dosya sonu geldiyse aşağıdaki mesaji bas

print (“– Kullanımdaki dosyanın Sonu –\n”);

}

}

çalışması; ./program.pl  dosya1  dosya2

 

Bu ilk dosyanın ilk satırı

Bu ilk dosyanın ikinci satırı

 

— Kullanımdaki dosyanın Sonu —

 

Bu ikinci dosyanın ilk satırı

Bu ikinci dosyanın ikinci satırı

 

— Kullanımdaki dosyanın Sonu —

 

Not:  dosya sonu kontrolünde eof ve eof() kullanılır ama ikisi birlikte kullanılmaz.

 

Şimdi de parantezli eof kullanımına bakalım.

Örnek :

#!/usr/local/bin/perl

while ($kayit = <>) {

print ($kayit);

if (eof()) {

print (“– Kullanımdaki dosyanın Sonu –\n”);

}

}

çalışması ; ./program.pl  dosya1  dosya2

 

Bu ilk dosyanın ilk satırı

Bu ilk dosyanın ikinci satırı

 

Bu ikinci dosyanın ilk satırı

Bu ikinci dosyanın ikinci satırı

 

— Kullanımdaki dosyanın Sonu —

 

Çıktıyı incelediğinizde  dosya sonu mesajının her dosyanın sonunda değil tüm dosyaların okunması

Sonunda bir defa yazdığını görüyorsunuz. eof() kullanımında ancak tüm  dosyalar bitince true döner. Birinci dosya sonunda kontrolde false ‘e döner. Çünkü sırada okunacak ikinci dosya vardır.

Yalnız şuna dikkat etmemiz gerekir eof ile eof() arasında sadece <> operatörüyle kullanımda fark vardır. Yalnız başlarına kullanımda eof ile eof() arasında fark yoktur.

 

DOSYA İSİMLERİNİN DOLAYLI KULLANIMI

 

$dosya = “DOSYAM”;

open ($dosya, “>dosya.dat”);     gibi…

 

Örnek :

 

#!/usr/local/bin/perl

 

&dosya_ac(“OKU”, “”, “dosya1”);

&dosya_ac (“YAZ”, “>”, “dosya2”);

while ($satir = &dosyadan_oku(“OKU”)) {

&dosyaya_yaz(“YAZ”, $satir);

}

 

 

sub dosya_ac {

local ($dosya_degiskeni, $dosya_modu, $dosya_adi) = @_;

open ($dosya_degiskeni, $dosya_modu . $dosya_adi) ||

die (“$dosya_adi  dosyası açılamadı… “);

}

 

 

sub dosyadan_oku {

local ($dosya_degiskeni) = @_;

<$dosya_degiskeni>;

}

 

 

sub dosyaya_yaz {

local ($dosya_degiskeni, $satir) = @_;

print $dosya_degiskeni($satir);

}

 

çalışması,

 

program ekrana çıktı vermez.   dosya1 adlı dosyayı dosya2 ye kopyalar.

more dosya1 veya cat dosya1 gibi komutlarla baktığımızda her iki dosyanın da içerik olarak aynı

olduğunu görürüz.

$  cat dosya1

Bu ilk dosyanın ilk satırı

Bu ilk dosyanın ikinci satırı

 

$  cat dosya2

Bu ilk dosyanın ilk satırı

Bu ilk dosyanın ikinci satırı

 

DATALARI ATLAMA VE YENİDEN OKUMA

 

==  seek  ==     ==  tell  ==

 

Şimdiye kadar hep ilk sıradan başlatarak  okuma örnekleri gördük.

Perl bize iki hazır fonksiyon sunar.Bunlar seek ve tell fonksiyonlarıdır. Bu fonksiyonlar dosyada ileri, geri

hareketi veya tekrar okuma gibi işlevlere sahiplerdir.

 

seek fonksiyonu : bu fonksiyon dosya içinde ileri ve geri hareketi sağlar. Formatı ;

 

            seek (dosyadeğişkeni, atlanacak karakter sayısı, konum_sabiti);                   

 

eğer konum sabiti;

0 ise; dosya başı

1 ise; bulunulan konum değeri

2 ise; dosya sonu anlamı taşırlar.

 

Örneğin; DOSYAM adlı dosyanın başına atlamak istiyorsak

seek (DOSYAM, 0, 0); kodlanır.

Yorum bırakın