Önceki bölümlerdeki programlar hep standart giriş ve çıkış akımları ile etkileşiyorlardı. D'nin standart akımlarının
stdin ve
stdout olduklarını görmüştük, ve açıkça akım bildirmeden çağrılan
writeln gibi işlevlerin de arka planda bu akımları kullandıklarını öğrenmiştik. Ek olarak, standart girişin hep klavye olduğu, ve standart çıkışın da hep ekran olduğu durumlarda çalışmıştık.
Bundan sonraki bölümde programları dosyalarla etkileşecek şekilde yazmayı öğreneceğiz. Dosyaların da karakter akımı olduklarını, ve bu yüzden standart giriş ve çıkışla etkileşmekten bir farkları olmadıklarını göreceksiniz.
Dosya akımlarına geçmeden önce, programcılık hayatınızda çok işinize yarayacak başka bir bilgiyi bu bölümde vermek istiyorum: programınızın standart giriş ve çıkışını, sizin kodunuzda hiçbir değişiklik gerekmeden dosyalara bağlayabilirsiniz. Programınız ekran yerine bir dosyaya yazabilir, ve klavye yerine bir dosyadan veya bir programdan okuyabilir. Bu, bütün modern uç birimlerin hepsinde bulunan ve programlama dilinden bağımsız bir olanaktır.
Programınızı bir uç birimden başlatıyorsanız, programı çalıştırmak için yazdığınız komutun sonuna
> karakterinden sonra bir dosya ismi yazmanız, programın standart çıkış akımının o dosyaya bağlanması için yeterlidir. Bu durumda, programın standart çıkışına yazdığı herşey o dosyaya yazılır.
Standart girişinden bir sayı alan, o sayıyı 2 ile çarpan, ve sonucu standart çıkışına yazdıran bir program düşünelim:
import std.stdio; void main() { double sayı; readf(" %s", &sayı); writeln(sayı * 2); }
O programın isminin
iki_kat olduğunu varsayarsak, programı komut satırından
./iki_kat > iki_kat_sonucu.txt
şeklinde başlatır ve girişine örneğin 1.2 yazarsanız, programın çıktısı olan 2.4'ün ekrana değil,
iki_kat_sonucu.txt ismindeki bir dosyaya yazıldığını görürsünüz. Not: Bu program baştan "Lütfen bir sayı giriniz: " gibi bir mesaj yazmadığı halde, siz yine de sayıyı klavyeden yazıp Enter'a basmalısınız.
Çıkışın
> karakteriyle bir dosyaya bağlanmasına benzer şekilde, giriş de
< karakteriyle bir dosyaya bağlanabilir. Bu durumda da girişinden bilgi bekleyen bir program klavyeden okumak yerine, belirtilen dosyadan okur.
Bu sefer de elimizde girişinden aldığı sayının onda birini hesaplayan bir program olsun:
import std.stdio; void main() { double sayı; readf(" %s", &sayı); writeln(sayı / 10); }
Eğer iki kat alan programın oluşturduğu dosya hâlâ klasörde duruyorsa, ve bu programın isminin de
onda_bir olduğunu varsayarsak, programı komut satırından
./onda_bir < iki_kat_sonucu.txt
şeklinde başlatırsanız, girişini daha önce oluşturulan
iki_kat_sonucu.txt dosyasından aldığını ve çıkışa
0.24 yazdırdığını görürsünüz. Not:
iki_kat_sonucu.txt dosyasında 2.4 olduğunu varsayıyorum.
onda_bir programı; ihtiyacı olan sayıyı artık klavyeden değil, bir dosyadan okumaktadır.
Giriş ve çıkış akımlarının ikisini birden dosyalara bağlamak
> ve
< karakterlerini aynı anda kullanabilirsiniz:
./onda_bir < iki_kat_sonucu.txt > butun_sonuc.txt
Bu sefer giriş
iki_kat_sonucu.txt dosyasından okunur, ve çıkış da
butun_sonuc.txt dosyasına yazılır.
Yukarıda kullanılan
iki_kat_sonucu.txt dosyasının iki program arasında aracılık yaptığına dikkat edin:
iki_kat programı, hesapladığı sonucu
iki_kat_sonucu.txt dosyasına yazmaktadır, ve
onda_bir programı da ihtiyaç duyduğu sayıyı
iki_kat_sonucu.txt dosyasından okumaktadır.
| karakteri, programları böyle bir aracı dosyaya gerek olmadan birbirlerine bağlar.
| karakteri, solundaki programın standart çıkışını sağındaki programın standart girişine bağlar. Örneğin komut satırında birbirine şu şekilde bağlanan iki program, toplu olarak "beşte bir" hesaplayan bir komut haline dönüşür:
./iki_kat | ./onda_bir
Önce
iki_kat programı çalışır ve girişinden bir sayı alır. Not: O programın "Lütfen bir sayı giriniz: " gibi bir mesaj yazmadığını hatırlayın; siz yine de sayıyı klavyeden yazıp Enter'a basmalısınız.
Sonra,
iki_kat programının çıkışı
onda_bir programının girişine verilir ve iki katı alınmış olan sayının onda biri, yani baştaki sayının "beşte biri" çıkışa yazılır.
Problem
İkiden fazla programı art arda bağlamayı deneyin:
./birinci | ./ikinci | ./ucuncu