GİRİŞ-ÇIKIŞ AKIMLARI
Java’da Giriş-Çıkış akımları, iki ana gruba ayrılır:
- Karakter kökenli akımlar
- Byte kökenli akımlar
Bunların herbiri için ayrı sınıflar tanımlanmıştır. Aşağıdaki şekil bu konuda bize fikir veriyor:
Karakter Kökenli Akımlar
Bu bölümde önce karakter kökenli akımlar ile bellek üzerindeki dosyalara bilgi kaydını gözden geçireceğiz. Bellek üzerine karakter türü bilgi kaydını Writer sınıfının alt sınıflarını kullanarak gerçekleştiriyoruz. Aşağıda, Writer sınıfıyla ilişkili sınıf hiyerarşisini görüyoruz:
FileWriter Sınıfının Kullanımı
Aşağıdaki örnek Java programı, FileWriter sınıfından yazar adlı bir nesne oluşturarak, bu nesne yardımıyla siir.txt adlı text tipi dosyaya bilgi kaydediyor. Dosyaya bir satırlık bilgi write metoduyla yazılıyor ve satır sonu ‘\n’ karakteriyle belirleniyor.
import java.io.FileWriter;
import java.io.IOException;
public class TextDosyaYaz {
public static void main(String[] args) throws IOException {
String dosyaAdi = "siir.txt";
FileWriter yazar = new FileWriter(dosyaAdi);
yazar.write("coklarindan dusuyor da bunca");
yazar.write("gormuyor gelip gecenler");
yazar.write("egilip aliyorum");
yazar.write("solgun bir gul oluyor dokununca - behcet necatigil");
yazar.close();
}
}
Uygulamayı Eclipse ile çalıştırdığımızda projenin bulunduğu dizinde bir siir.txt dosyasının oluşturulduğunu görürüz:
Dosyayı açtığımızdaysa aşağıdaki içeriği görürüz:
Metin türünde bir dosyanın içeriğinin herhangi bir metin düzenleyici program yardımıyla görüntülenebileceğini belirtmiştik. Burada bunun örneğini görmüş olduk. siir.txt adlı dosyanın içeriğini bir Java programıyla da görüntüleyebiliriz. Bunun örneğini de biraz sonra göreceğiz. Ancak, byte tipi ya da ikili(binary) dosyaların içeriği sadece Java programı yardımıyla görüntülenebilir.
Metin Türü Dosyadan Bilgi Okumak
Metin türü bir dosyadan bilgi okumak için Reader sınıfını ve alt sınıflarını kullanırız. Aşağıda Reader sınıfı ve ilgili sınıfların hiyerarşisini görüyoruz:
FileReader sınıfı sayesinde disk üzerindeki metin tipi dosyadan alınan karakterler, bellek içinde char tipine dönüştürülür. Eğer UTF formatıyla desteklenen, İngiliz alfabesi dışındaki karakterler kullanılmışsa bir karakter 3 byte’lık yer kaplamış olabilir.
Diskten okunan verilerin önce bellekte bir tampon alan(buffer) içine yerleştirilmesi genellikle daha etkin bir yöntemdir. BufferedReader sınıfı bu amaçla kullanılır.
ÖRNEK JAVA PROGRAMI: FileReader ve BufferedReader ile Okuma
Bir önceki örnekte siir.txt adı ile oluşturduğumuz dosyayı şimdi bir Java programı ile okuyarak ekrana aktaracağız:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TextDosyaOku {
public static void main (String[] args){
String dosyaAdi = "siir.txt";
String satir;
try{
BufferedReader oku = new BufferedReader(new FileReader(dosyaAdi));
satir = oku.readLine();
while (satir != null) {
System.out.println(satir);
satir = oku.readLine();
}
oku.close();
}
catch (IOException iox){
System.out.println(dosyaAdi+" adli dosya okunamiyor.");
}
}
}
Aşağıda olduğu gibi, siir.txt adlı metin dosyasının içeriğinin listelendiğini görürüz:
ÖRNEK UYGULAMA: Bir Metin Dosyasının İçeriğini Diğer Bir Metin Dosyasına Kopyalama
Aşağıdaki Java programı ile komut satırından adı girilen bir dosyanın içeriği yine komut satırından adı belirtilen diğer bir dosyaya kopyalanabiliyor. Aşağıdaki adımları izleyelim:
1. Aşağıdaki Java program bloğunu yazalım:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Kopyala{
String kaynakDosyaAdi, hedefDosyaAdi;
BufferedReader kaynakBuffer;
BufferedWriter hedefBuffer;
String satir;
public static void main (String[] args) {
if (args.length == 3 && args[1].toUpperCase().equals("TO")) {
new Kopyala().kopya(args[0], args[2]);
}
else {
System.out.println("Kullanim sekli: ");
System.out.println("java Kopyala <dosya1> to <dosya2>");
}
}
public boolean kopya(String isim1, String isim2) {
kaynakDosyaAdi=isim1;
hedefDosyaAdi=isim2;
return dosyayiAc() && dosyayiKopyala() && dosyayiKapat();
}
private boolean dosyayiAc() {
// Kaynak dosyayı aç
try {
kaynakBuffer = new BufferedReader(
new FileReader(kaynakDosyaAdi));
}
catch (IOException e) {
System.out.println(kaynakDosyaAdi
+" dosyasinin acilisinda sorun var!");
return false;
}
// Hedef dosyayı aç
try {
hedefBuffer = new BufferedWriter(
new FileWriter(hedefDosyaAdi));
}
catch (IOException e) {
System.out.println(hedefDosyaAdi
+" dosyasinin acilisinda sorun var!");
return false;
}
return true; //iki dosya da ulasilabilirse true döndürür
}
private boolean dosyayiKopyala() {
//esas metodumuz
try {
satir = kaynakBuffer.readLine();
while (satir != null) {
hedefBuffer.write(satir);
hedefBuffer.newLine();
satir = kaynakBuffer.readLine();
}
}
catch (IOException e) {
System.out.println("Kopyalama yapilamiyor.");
return false;
}
return true;
}
private boolean dosyayiKapat() {
boolean sorunsuzMu=true;
// kaynağı kapat
try {
kaynakBuffer.close();
}
catch (IOException e) {
System.out.println(kaynakDosyaAdi+" dosyasinin kapanisinda hata!");
sorunsuzMu = false;
}
// hedefi kapat
try {
hedefBuffer.close();
}
catch (IOException e) {
System.out.println(hedefDosyaAdi+" dosyasinin kapanisinda hata!");
sorunsuzMu = false;
}
return sorunsuzMu;
}
}
2. Komut satırından aşağıdaki komutu girelim:
Böylece siir.txt adlı dosyanın içeriği aynen manzum.txt adlı metin dosyasına kopyalanır.
İKİLİ (BINARY) DOSYALAR
Metin tipi dosyalarda, her byte veya byte ikilisi bir ASCII kodu şeklinde yorumlanırken, ikili dosyalarda değişik uzunluklardaki byte grupları farklı türlerdeki veri olarak yorumlanır. Bu yorum yazılım tarafından gerçekleştirilir. Örneğin, bir Java binary dosyasında, bir int türü veri 4 byte’lık bir veri grubuyla saklanır.
İkili (binary) dosyaya veri kaydetmek için temel sınıf OutputStream sınıfıdır. Aşağıdaki şekilde bu sınıf ve alt sınıflarını görüyoruz:
Aşağıdaki kod örneği ikili dosyaların birbirine kopyalanmasını gösterir.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IkiliDosya {
public static void main(String[] args) {
//Dosyalarınızın yolunu belirtin.
String kaynakDosya = "Kaynak dosyanın yolu";
String hedefDosya = "Hedef dosyanın yolu";
try {
//Kopyalama işlemi için InputStream ve OutputStream nesnelerinizi oluşturun.
FileInputStream fis = new FileInputStream(kaynakDosya);
FileOutputStream fos = new FileOutputStream(hedefDosya);
//Kopyalanacak satırın ilk harfinin yerini belirtin.
int offset = 0;
//Kopyalanacak satirin boyutunu tanımlayın.
int satirinboyutu = 0;
//Kopyalanacak satır için array oluşturun.
byte[] satir = new byte[1024];
//İlk satırı okuyup boyutunu alın.
satirinboyutu = fis.read(satir);
//Okunan satırların boyutu -1 değilse, yani sona gelinmediyse kopyalayın.
while (satirinboyutu != -1) {
//Hedef dosyaya yazın.
fos.write(satir, offset, satirinboyutu);
//Yeni bir satır okuyun.
satirinboyutu = fis.read(satir);
}
//Her iki dosyayı da kapatın.
fis.close();
fos.close();
}
catch (IOException e) {
//Bir hata durumunda programınıza uyarı verdirin.
System.out.println("Bir hata oluştu " + e);
}
}
}