Java Dosya Açma, Okuma, Yazma ve Düzenleme İşlemleri
14 min read

Java Dosya Açma, Okuma, Yazma ve Düzenleme İşlemleri

Java Dosya Açma, Okuma, Yazma ve Düzenleme İşlemleri

Java dosya işlemleri dilin temellerini oluşturan en önemli konulardan birisidir. Temeli iyi atmak içinde geniş bir dosya işlemleri konusu yazma ihtiyacı duydum. El kitabı niteliği taşıyacak bu yazı ile dosyalar üzerinde aradığınız birçok özelliğe kolayca erişebileceksiniz.

Programlama yaparken, ister bir mobil uygulama, ister bir web uygulaması oluşturuyor olun, ister sadece komut dosyaları yazıyor olun, genellikle bir dosyaya veri okuma veya yazma ihtiyacı duyarsınız. Bu veriler önbellek verileri, bir veri kümesi için aldığınız veriler, bir görüntü veya aklınıza gelebilecek herhangi bir şey olabilir. Bu eğiticide, Java’daki dosyaları okuyup yazmanın en yaygın yollarını göstereceğiz.

Java’da dosya okuma ve yazma işlemleri için File ve I/O sınıflarını kullanırız. Bu nedenle dosya işlemlerine geçmeden önce File sınıfını inceleyerek başlayalım. Ardından kullanacağımız I/O sınıflarını öğrenmek daha etkili olacaktır.

1. File Sınıfı

Java File sınıfı, dosyaları ve dizin yol adlarını soyut bir şekilde temsil eder. Bu sınıf, dosya ve dizinlerin oluşturulması, dosya arama, dosya silme vb. için kullanılır. File nesnesi, diskteki gerçek dosyayı/dizini temsil eder. File nesnesi oluşturmak için yapıcıların (constructer) listesi aşağıdadır.

  • File(File parent, String child): Bu yapıcı, bir ana soyut yol adından ve bir alt yol adı dizesinden yeni bir File örneği oluşturur.
  • File(String pathname): Bu yapıcı, verilen yol adı dizesini soyut bir yol adına dönüştürerek yeni bir File örneği oluşturur.
  • File(String parent, String child): Bu yapıcı, bir üst yol adı dizesinden ve bir alt yol adı dizesinden yeni bir File örneği oluşturur.
  • File(URI uri): Bu yapıcı, verilen dosyayı (URI) soyut bir yol adına dönüştürerek yeni bir File örneği oluşturur.

Elinizde File nesnesine sahip olduğunuzda, dosyaları işlemek için kullanılabilecek yardımcı yöntemlerin bir listesi aşağıdaki gibidir:

  • getName(): Dosyanın veya dizinin adını döndürür.
  • getParent(): Soyut yol adının üst dizininin yol adı dizesini veya bu yol adı bir üst dizini adlandırmıyorsa null döndürür.
  • getParentFile(): Soyut yol adının üst öğesinin soyut yol adını veya bu yol adı bir üst dizini adlandırmıyorsa null döndürür.
  • getPath(): Soyut yol adını bir yol adı dizesine dönüştürür.
  • isAbsolute(): Soyut yol adının mutlak olup olmadığını test eder. Bu soyut yol adı mutlaksa true, aksi takdirde false döndürür.
  • getAbsolutePath(): Soyut yol adının mutlak yol adı dizesini döndürür.
  • canRead(): Uygulamanın dosyayı okuyup okuyamadığını test eder. (Okuma izni)
  • canWrite(): Uygulamanın dosyayı değiştirip değiştiremeyeceğini test eder. (Yazma izni)
  • exists(): SDosyanın veya dizinin var olup olmadığını test eder.
  • isDirectory(): Dosyanın bir dizin olup olmadığını test eder.
  • isFile(): Dosyanın bir dosya olup olmadığını test eder.
  • lastModified(): Dosyanın en son değiştirildiği zamanı döndürür.
  • length(): Dosyanın uzunluğunu döndürür.
  • createNewFile(): Bu ada sahip bir dosya henüz mevcut değilse, yeni, boş bir dosya oluşturur. Dosya zaten varsa False döndürür.
  • delete(): Dosyayı siler.
  • deleteOnExit(): Dosyanın veya dizinin, sanal makine sona erdiğinde silinmesini ister.
  • list(): Dizindeki dosya ve dizinleri bir dizi olarak dizisi döndürür.
  • listFiles(): Dizindeki dosya dosyaları bir dizi olarak dizisi döndürür.
  • mkdir(): Bu soyut yol adıyla adlandırılan dizini oluşturur
  • mkdirs(): Gerekli olan ancak var olmayan ana dizinler dahil olmak üzere bu soyut yol adıyla adlandırılan dizini oluşturur.
  • renameTo(File dest): Dosyayı yeniden adlandırır.
  • setLastModified(long time): Dosya veya dizinin son değiştirilme zamanını belirler.
  • setReadOnly(): Dosya veya dizini yalnızca okuma işlemlerine izin verecek şekilde işaretler.
  • compareTo(File pathname): İki soyut yol adını sözlükbilimsel olarak karşılaştırır. Bağımsız değişken bu soyut yol adına eşitse sıfır, bu soyut yol adı sözlükbilimsel olarak bağımsız değişkenden küçükse sıfırdan küçük bir değer veya bu soyut yol adı sözlükbilimsel olarak bağımsız değişkenden büyükse sıfırdan büyük bir değer döndürür.
  • equals(Object obj): Bu soyut yol adını verilen nesneyle eşitlik açısından test eder. Yalnızca ve ancak bağımsız değişken boş değilse ve bu soyut yol adıyla aynı dosya veya dizini belirten soyut bir yol adı ise true döndürür.
  • toString(): Bu soyut yol adının yol adı dizesini döndürür. Bu yalnızca getPath() yöntemi tarafından döndürülen dizedir.

2. I/O Stream Türleri

Java, ilk sürümlerinden bu yana dosyaları okumak ve yazmak için birkaç API (Java I/O olarak da bilinir) sağlar. Sonraki sürümlerle birlikte Java I/O, yeni özellikleri desteklemek için iyileştirildi, basitleştirildi ve geliştirildi.

Bazı gerçek örneklere geçmeden önce, verinin dosyalara okunması ve yazılmasıyla ilgilenecek, kullanabileceğiniz sınıfları anlamamız yardımcı olacaktır. Aşağıdaki bölümlerde Java I/O sınıflarına kısa bir genel bakış sunacağız ve ne yaptıklarını açıklayacağız, ardından Java NIO Akışlarına bir göz atacağız ve son olarak bazı verileri okuma ve yazma örneklerini göstereceğiz.

988x660

Java’da akışlar (streams), kaynaktan okunan ve hedefe yazılan veri dizisidir. Kaynaktan veri okumak için bir giriş akışı (input) kullanılır ve hedefe veri yazmak için bir çıktı akışı (output) kullanılır. Bu iki temel işlem I/O’yu oluşturur. Şimdi bu I/O akışların tiplerini öğrenelim.

Bir akışın tuttuğu verilere bağlı olarak şu şekilde sınıflandırılabilir:

  1. Character Stream
  2. Byte Stream

2.1. Character Stream

Karakter akışı, tek bir veri karakterini okumak ve yazmak için kullanılır. Tüm karakter akışı sınıfları, Reader ve Writer temel abstract (soyut) sınıflarından türetilir. Bu abstract sınıfların kullanacağımız alt sınıfları şunlardır;

Reader sınıfının bazı alt sınıfları;

  • FileReader,
  • InputStreamReader,
  • BufferedReader,
  • StringReader,
  • CharArrayReader,
  • FilterReader,
  • PipedReader,

Writer sınıfının bazı alt sınıfları;

  • FileWriter,
  • OutputStreamWriter,
  • BufferedWriter,
  • StringWriter,
  • CharArrayWriter,
  • FilterWriter,
  • PipedWriter,
  • PrintWriter

2.2. Byte Stream

Bayt akışı, tek baytlık (8 bit) veriyi okumak ve yazmak için kullanılır. Tüm byte stream sınıfları, InputStream ve OutputStream adlı temel abstract (soyut) sınıflardan türetilir. Bu abstract sınıfların kullanacağımız alt sınıfları şunlardır;

InputStream sınıfının bazı alt sınıfları;

  • FileInputStream,
  • ByteArrayInputStream,
  • ObjectInputStream,
  • BufferedInputStream,
  • FilterInputStream,
  • AudioInputStream,
  • PipedInputStream,
  • SequenceInputStream,
  • StringBufferInputStream

OutputStream sınıfının bazı alt sınıfları;

  • FileOutputStream,
  • ByteArrayOutputStream,
  • ObjectOutputStream,
  • BufferedOutputStream,
  • FilterOutputStream,
  • PipedOutputStream
  • PrintStream

Bu sınıflardan en çok kullanılanları tek tek sonraki başlıklarda inceleyeceğiz.

3. Java NIO Streams

Java NIO, Java 4’te sunulan ve java.nio paketinde bulunabilen, non-blocking I/O API‘sidir. Performans açısından, I/O işlemleri için API’de büyük bir gelişmedir.

Buffers (tamponlar), Selectors (seçiciler) ve Channels (kanallar), Java NIO’nun üç ana bileşenidir, ancak bu makalede, API’nin arkasındaki kavramlara değil, dosyalarla etkileşim için kesinlikle NIO sınıflarını kullanmaya odaklanacağız.

Bu eğitim dosyaları okumak ve yazmakla ilgili olduğundan, bu kısa bölümde yalnızca ilgili sınıfları tartışacağız:

  1. Path (Yol): Gerçek bir dosya konumunun hiyerarşik bir yapısıdır ve genellikle etkileşimde bulunmak istediğiniz dosyayı bulmak için kullanılır.
  2. Paths (Yollar): Belirli bir string URI’sinden Path oluşturmak için birkaç yardımcı yöntem sağlayan bir sınıftır.
  3. Files (Dosyalar): Thread’ler üzerinde yürütmeyi engellemeden dosyaları okumak ve yazmak için çeşitli yöntemler içeren başka bir yardımcı program sınıfıdır.

4. Java I/O ve NIO Arasındaki Fark

Bu iki paket arasındaki temel fark, Java IO’nun read() ve write() yöntemlerinin bloke edici çağrılar olmasıdır. Bununla, bu yöntemlerden birini çağıran iş parçacığının (thread), veriler okunana veya dosyaya yazılıncaya kadar engelleneceğini kastediyoruz.

Öte yandan, NIO durumunda, yöntemler engelleyici değildir. Bu, okuma veya yazma yöntemleri işlemlerinin tamamlanmasını beklerken, çağıran iş parçacıklarının başka görevleri (başka bir kaynaktan veri okuma / yazma veya kullanıcı arayüzünü güncelleme gibi) gerçekleştirebileceği anlamına gelir. Bu, çok sayıda I/O isteğiyle veya çok sayıda veriyle uğraşıyorsanız önemli bir performans artışı sağlayabilir.

5. Metin Dosyalarını Okuma ve Yazma Örnekleri

Önceki bölümlerde, Java tarafından sağlanan farklı API’leri tartıştık ve şimdi bu API sınıflarını bazı kodlarda kullanma zamanı. Aşağıdaki örnek kod, yukarıda detaylandırdığımız çeşitli sınıfları kullanarak metin dosyalarının okunmasını ve yazılmasını ele alır. İşleri basitleştirmek ve kullanılan gerçek yöntemlerin daha iyi bir karşılaştırmasını sağlamak için, giriş ve çıkış örnekler arasında aynı kalacaktır.

Not: Dosya yolunda herhangi bir karışıklığı önlemek için, örnek kod kullanıcının ana dizinindeki bir dosyadan okuyacak ve yazacaktır. Kullanıcının ev dizini, bizim örneklerimizde kullandığımız System.getProperty("user.home"); kullanılarak bulunabilir.

5.1 Dosya Seçme ve Oluşturma

File sınıfı sayesinde disk üzerinde bulunan dosyayı program içinde bir nesne haline getirebilir, yoksa oluşturabilir ve programcının dosya üzerinde işlem yapabilmesini mümkün hale getirebiliriz. İlk olarak dosya seçme işlemine bakalım;

String dosyayolu = "C:\\Users\\kerteriz\\Desktop\\deneme.txt";
File f = new File(dosyayolu);

Not: Burada dosya yolunu belirtirken escape karakteriyle beraber kullanmanız, yani \\ ile pathi oluşturmanız gerekmektedir.

Dosyanın olmaması durumda hata ile karşılaşmamak için exists() methodu ile dosyanın varlığını kontrol edebilir, createNewFile() yöntemi ile de dosyayı oluşturabilirsiniz.

String dosyayolu = "C:\\Users\\kerteriz\\Desktop\\deneme.txt"
File f = new File(dosyayolu)
if(f.exists()) // Dosyanın var olup olmadığı kontrol edilir.
{
    // işlemler
}
else {
    f.createNewFile(); // Dosya yok ise oluşturur.
}

5.2 Dosya Silme

File sınıfını kullanarak herhangi bir dosyayı silmek için delete() yöntemini kullanabilirsiniz. Öncesinde dosyanın var olup olmadığını kontrol etmeniz iyi bir kullanım olacaktır.

String dosyayolu = "C:\\Users\\kerteriz\\Desktop\\deneme.txt"
File f = new File(dosyayolu)
if(f.exists()) // Dosyanın var olup olmadığı kontrol edilir.
{
    f.delete(); // Dosyayı siler
}

5.3 Dosya İsmini Değiştirme

Yine File sınıfı sayesinde elimizdeki bir dosyanın ismini renameTo() methoduyla rahatlıkla değiştirebiliriz.

File oldFile = new File("C:\\xx.txt");
File newFile = new File("C:\\yy.txt");

if(oldFile.exists()) // Dosyanın var olup olmadığı kontrol edilir.
{
    oldFile.renameTo(newFile);
}

5.4 Dosya Bilgilerini Almak

Yine aynı File sınıfı ile elinizdeki dosyalar hakkında geniş bilgiler elde edebilirsiniz. Elde edebileceğiniz bilgiler için en çok kullanılan yöntemleri aşağıdaki örnekte bulabilirsiniz;

  • getName(): Dosya adını verir
  • getAbsolutePath(): Dosyanın tam yolunu verir
  • getTotalSpace(): Dosyanın boyutunu verir
  • getParentFile(): Bir üst dizinini verir
  • canRead(): Dosya okuma izni varsa True, yoksa False döner
  • canWrite(): Dosya yazma izni varsa True, yoksa False döner
  • isFile(): Dosya ise True, değilse False Döner
  • isDirectory(): Dizin ise True, değilse False Döner

Çok daha fazlasını editörünüzün autocomplete özelliğini kullanarak elde edebilirsiniz.

5.5 Dosya Okuma ve Yazma Örnekleri

Bu bölümde yukarıda bahsettiğimiz sınıflardan en çok kullanılanları ile dosya okuma ve yazma örneklerini göreceğiz.

5.5.1 FileReader ve FileWriter ile Okuma ve Yazma

FileReader ve FileWriter sınıflarını kullanarak başlayalım. İlk olarak okuma işlemine bakalım;

Dosya okuma işlemini iki türlü yapabilirsiniz. Bunlardan birisi char[] oluşturarak dosya içeriğini read(char[]) yöntemiyle diziye aktarmak ve ardından dizi elemanlarını yazdırmaktır.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

char[] dizi = new char[100];

try {
    FileReader fileReader = new FileReader(absolutePath);
    fileReader.read(dizi);
    System.out.print(dizi);
    fileReader.close();
} catch (IOException e) {
    // Exception handling
}

Fakat eğer dosyada bulunan karakter sayısı oluşturduğunuz char dizisinin boyutundan büyükse veriyi eksik almış olursunuz. Bu nedenle read() yöntemiyle dosyayı karakter karakter okumak ve ekrana basmak daha doğru yöntemdir. Okunacak veri kalmadığında sonuç -1 dönecektir.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

try {
    FileReader fileReader = new FileReader(absolutePath);

    int ch = fileReader.read();
    while (ch != -1) {
        System.out.print((char) ch);
        ch = fileReader.read();
    }

    fileReader.close();
} catch (IOException e) {
    // Exception handling
}

Şimdide dosyaya yazma örneğimize bakalım. write() methoduna ister String isterseniz de char[] verebilirsiniz.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

try {
    FileWriter fileWriter = new FileWriter(absolutePath);
    String text = "Bu örnek bir metindir.";
    fileWriter.write(text);
    fileWriter.close();
} catch (IOException e) {
    // Exception handling
}

Not: Unutmayınız ki yazma işlemi mevcut verinin üstüne yazar.

5.5.2 InputStreamReader ve InputStreamWriter ile Okuma ve Yazma

InputStreamReader ve InputStreamWriter sınıflarını kullanarak devam edelim. InputStreamReader sınıfı, diğer input streamlerle çalışır. Bayt akışları ve karakter akışları arasında bir köprü olarak da bilinir. Bunun nedeni, InputStreamReader‘ın giriş akışındaki baytları karakter olarak okumasıdır.

Örneğin, bazı karakterlerin hafızada depolanması için 2 bayt gerekiyor. Bu tür verileri okumak için, 2 baytı birlikte okuyan ve karşılık gelen karaktere dönüştüren giriş akışı okuyucusunu kullanabiliriz.

İlk olarak okuma işlemine bakalım. InputStreamReader öncelikle bir input stream parametresi alacaktır. Bunun için FileInputStream i dosya yolumuz ile oluşturuyoruz.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

FileInputStream file = new FileInputStream(absolutePath);
InputStreamReader input = new InputStreamReader(file);

Burada, dosyadaki veriler bazı varsayılan karakter kodlamaları kullanılarak saklanır.Bununla birlikte, dosyada karakter kodlama türünü (UTF8 veya UTF16) da belirtebiliriz.

Charset cs = Charset.forName("UTF8");
InputStreamReader input = new InputStreamReader(file, cs);

Mevcut bir dosyanın Charset’ini öğrenmek için getEncoding() yöntemini kullanabilirsiniz. Örneğin;

FileInputStream file = new FileInputStream("test.txt");
InputStreamReader input1 = new InputStreamReader(file);
InputStreamReader input2 = new InputStreamReader(file, Charset.forName("UTF8"));

System.out.println("Character encoding of input1: " + input1.getEncoding());    // Cp1252
System.out.println("Character encoding of input2: " + input2.getEncoding());    // UTF8

Asıl kısma gelirsek, dosya okuma işlemini iki türlü yapabilirsiniz. Bunlardan birisi char[] oluşturarak dosya içeriğini read(char[]) yöntemiyle diziye aktarmak ve ardından dizi elemanlarını yazdırmaktır.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

char[] dizi = new char[100];

try {
    FileInputStream file = new FileInputStream(absolutePath);
    InputStreamReader input = new InputStreamReader(file);
    input.read(dizi);
    System.out.print(dizi);
    input.close();
} catch (IOException e) {
    // Exception handling
}

Fakat eğer dosyada bulunan karakter sayısı oluşturduğunuz char dizisinin boyutundan büyükse veriyi eksik almış olursunuz. Bu nedenle read() yöntemiyle dosyayı karakter karakter okumak ve ekrana basmak daha doğru yöntemdir. Okunacak veri kalmadığında sonuç -1 dönecektir.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

try {
    FileInputStream file = new FileInputStream(absolutePath);
    InputStreamReader input = new InputStreamReader(file);

    int ch = input.read();
    while (ch != -1) {
        System.out.print((char) ch);
        ch = input.read();
    }

    input.close();
} catch (IOException e) {
    // Exception handling
}

Şimdide dosyaya yazma örneğimize bakalım. write() methoduna ister String isterseniz de char[] verebilirsiniz.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

try {
    FileOutputStream file = new FileOutputStream(absolutePath);
    OutputStreamWriter output = new OutputStreamWriter(file); 
    String text = "Bu örnek bir metindir.";
    output.write(text);
    output.close();
} catch (IOException e) {
    // Exception handling
}

5.5.3 BufferedReader ve BufferedWriter ile Okuma ve Yazma

BufferedReader ve BufferedWriter, default olarak 8192 karakterlik bir dahili arabellek (buffer) tutar. BufferedReader’daki okuma işlemi sırasında, diskten bir yığın karakter okunur ve dahili tamponda saklanır. Ve dahili tampondan karakterler ayrı ayrı okunur. Böylelikle diskle iletişim sayısı azalır. BufferedReader kullanarak karakterleri okumak daha hızlı olmasının nedeni budur.

İlk olarak okuma işlemine bakalım. Bunun için parametre olarak ilk FileReader oluşturmalı ve BufferedReader a parametre olarak vermeliyiz.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

// Dosyadan içeriği okuyalım
try {
    FileReader file = new FileReader(absolutePath);
    BufferedReader input = new BufferedReader(file);

    String line = input.readLine();
    while(line != null) {
            System.out.println(line);
            line = input.readLine();
    }
} catch (Exception e) {
    // Exception handling
}

Sıradan yazma işlemine bakalım.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

// Dosya içine metin yazalım 
try {
    String text = "Merhaba Kerteriz Blog okuyucuları!";

    FileWriter file = new FileWriter(absolutePath);
    BufferedWriter output = new BufferedWriter(file);

    output.write(text);
    output.close();
} catch (Exception e) {
    // Exception handling
}

Default olarak gelen buffer boyutunu değiştirmek isterseniz constructora bir FileReader, FileWriter objesi verirken buffer boyutunu da verebilirsiniz.

int size = 16384;
BufferedReader input = new BufferedReader(file, size);
BufferedWriter output = new BufferedWriter(file, size);

5.5.4 StringReader ve StringWriter ile Okuma ve Yazma

StringReader ve StringWriter ile String değişkenleri üzerinde çalışabilirsiniz. İlk olarak okuma işlemine bakalım;

String text = "Merhaba Kerteriz Blog okuyucuları!";
StringReader input = new StringReader(text);

try {
    int i = input.read();
    while (i != -1) {
        System.out.print((char) i);
        i = reader.read();
    }
} catch (IOException e) {
    // Exception handling
}

Şimdi ise yazma işlemine bakalım;

String text = "Merhaba Kerteriz Blog okuyucuları!";
StringWriter output = new StringWriter();

try {
    output.write(text);
    System.out.println("Data: " + output);
} catch (Exception e) {
    // Exception handling
}

5.5.5 PrintWriter ile Okuma ve Yazma

Diğer yöntemlerin aksine, PrintWriter ilkel verileri (int, float, char, vb.) String formatına dönüştürür. Daha sonra bu biçimlendirilmiş verileri yazar. Ayrıca, PrintWriter sınıfı herhangi bir I/O exception atmaz. Bunun yerine, içindeki herhangi bir hatayı bulmak için checkError() yöntemini kullanmamız gerekir.

Not: PrintWriter sınıfı ayrıca bir otomatik temizleme (auto flushing) özelliğine sahiptir. Bu, yazıcıyı println() veya printf() yöntemlerinden biri çağrılırsa hedefe tüm verileri yazmaya zorladığı anlamına gelir.

Veri yazdırırken ister direkt PrintWriter kullanabilir, isterseniz bir writer veya output stream yardımıyla veri yazdırabilirsiniz.

try {
    FileWriter file = new FileWriter("output.txt");
    PrintWriter output = new PrintWriter(file, autoFlush);

    output.print(data);
    output.close();
} catch(Exception e) {
    e.getStackTrace();
}

Veya

try {
    FileOutputStream file = new FileOutputStream("output.txt");
    PrintWriter output = new PrintWriter(file, autoFlush);

    output.print(data);
    output.close();
} catch(Exception e) {
    e.getStackTrace();
}

Veya

String data = "Kerteriz Blog";

try {
    PrintWriter output = new PrintWriter("output.txt");

    output.print(data);
    output.close();
}
catch(Exception e) {
    e.getStackTrace();
}

5.5.6 FileInputStream ve FileOutputStream ile Okuma ve Yazma

Karakter akışlarından sonra şimdi de byte akışlarına örnekler vermeye başlayalım. İlk olarak da FileInputStream ve FileOutputStream sınıflarını kullanalım:

Dosya okuma örneğimizle başlayalım;

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

// Dosyadan içeriği okuyalım
try {
    FileInputStream fileInputStream = new FileInputStream(absolutePath);
    int ch = fileInputStream.read();
    while(ch != -1) {
            System.out.print((char) ch);
            ch = fileInputStream.read();
    }
} catch (Exception e) {
    // exception handling
}

Ayrıca dosyada kaç byte olduğunu available() fonksiyonu ile kontrol edebilirsiniz

System.out.println(fileInputStream.available());

Dosyaya yazma örneğiyle devam ediyoruz.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

// Dosya içine metin yazalım 
try {
    FileOutputStream fileOutputStream = new FileOutputStream(absolutePath);
    String fileContent = "Bu örnek bir metindir.";
    fileOutputStream.write(fileContent.getBytes());
} catch (Exception e) {
    // exception handling
}

5.5.7 ByteArrayInputStream ve ByteArrayOutputStream ile Okuma ve Yazma

ByteArrayInputStream ve ByteArrayOutputStream sınıflarını kullanalım. Byte array kaynağımızdan okuma işlemi yaparak başlayalım.

byte[] array = {1, 2, 3, 4};

try {
    ByteArrayInputStream input = new ByteArrayInputStream(array);

    for(int i= 0; i < array.length; i++) {
        int data = input.read();
        System.out.print(data + ", ");
    }
    input.close();
}

catch(Exception e) {
    e.getStackTrace();
}

Konsola yazma örneğimizle devam edelim.

String data = "Kerteriz Blog ile profesyonel blogculuk";

try {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] array = data.getBytes();

    // output stream e veriyi yazalım
    out.write(array);

    // output stream i stringe çevirelim
    String streamData = out.toString();
    System.out.println("Output stream: " + streamData);

    out.close();
} catch(Exception e) {
    e.getStackTrace();
}

5.5.8 BufferedInputStream ve BufferedOutputStream ile Okuma ve Yazma

BufferedInputStream ve BufferedOutputStream sınıfları, 8192 baytlık bir dahili arabelleği kullanır. Okuma ve yazma işlemi sırasında, bir bayt yığını alınır ve dahili tamponda saklanır. Ve dahili tampon baytlarından ayrı ayrı okunur. Böylece diskle olan temas azaltılarak hız artırılır.

String directory = System.getProperty("user.home");
String fileName = "test.txt";
String absolutePath = directory + File.separator + fileName;

// Dosya içine metin yazalım 
try {
    FileOutputStream out = new FileOutputStream(absolutePath);
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream();

    String fileContent = "Bu örnek bir metindir.";
    bufferedOutputStream.write(fileContent.getBytes());
} catch (IOException e) {
    // exception handling
}

// Dosyadan içeriği okuyalım
try {
    FileInputStream input = new FileInputStream(absolutePath);
    BufferedInputStream bufferedInputStream = new BufferedInputStream();

    int ch = bufferedInputStream.read();
    while(ch != -1) {
            System.out.print((char)ch);
            ch = bufferedInputStream.read();
    }
} catch (FileNotFoundException e) {
    // exception handling
} catch (IOException e) {
    // exception handling
}

6. SONUÇ

Java dosyalar konusuna olabildiğince geniş şekilde baktık. Sormak istediğiniz veya eklememizi istediğiniz başlıklar olursa aşağıdaki yorum alanından belirtebilirsiniz. Bir sonraki yazıda görüşmek üzere..