/*----------------------------------------------------------------------------------------------------------------------
07.11.2020
BitConverter gibi bir sınıf yazılarak byte dizisi ve temel türler (+ string sınıfı) arasındaki dönüşümler
daha basitleştirilebilir
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import org.csystem.util.converter.BitConverter;
import java.io.FileOutputStream;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(args[0], true)) {
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
byte [] data = BitConverter.getBytes(text);
byte [] dataLen = BitConverter.getBytes((short)data.length);
fileOutputStream.write(dataLen);
fileOutputStream.write(data);
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
BitConverter gibi bir sınıf yazılarak byte dizisi ve temel türler (+ string sınıfı) arasındaki dönüşümler
daha basitleştirilebilir
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import org.csystem.util.converter.BitConverter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileInputStream fileInputStream = new FileInputStream(args[0])) {
for (;;) {
byte [] dataLen = new byte[2];
int read = fileInputStream.read(dataLen);
if (read == -1)
break;
if (read != 2)
throw new IOException("Dosya formatı bozuk");
short len = BitConverter.toShort(dataLen);
byte [] data = new byte[len];
read = fileInputStream.read(data);
if (read != len)
throw new IOException("Dosya formatı bozukx");
String text = BitConverter.toString(data);
System.out.println(text);
}
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Yazma ve Okuma İşlemini Kolaylaştıran Adaptör Sınıflar
Önceki konularda da gördüğümüz gibi bizim bir blgiyi dosyaya yazabilmemiz için önce onu byte dizisine dönüştürmemiz
sonra da write metoduyla bu işi yapmamız gerekir. Benzer biçimde bir dosyadan okuma yaparken de biz read metoduyla
önce istediğimiz bilgiyi byte dizisi olarak okuyup sonra da ilgili türe dönüştürmemiz gerekir. İşte bu işlem biraz
yorucudur. Üstelik String türü de işin içine girdiğinda yazı değişken uzunlukta tutulacaksa uzunluk bilgisinin
eklenmesi gibi durumlar da programcının sorumluluğunda olacaktır. Bu işlemleri kendi içerisinde yapan adaptör
sınıflar vardır. Bu adaptör sınıflar aslında sadece dosya işlemlerinde kullanılmaz. Genel okuma ve yazma sınıflarıdır.
Yani örneğin bir ağ üzerinde uzak bir makinaya veri gönderme ve alma durumlarında da kullanılabilir.
Genel olarak yani normal olarak yazma işlemi adaptör sınıfla yapılmışsa okuma işlemi de ilgili adaptör sınıfla ve
yazmaya karşılık gelen metotla yapılmalıdır. Aksi durumda verinin istenilen kısmı elde edilemeyebilir.
Anahtar Notlar: Dosyaya yazma yapan ve dosyadan okuma yapan uygulamaların her ikisi de okuma ve yazma işlemini
adaptör sınıflar yaparsa özellikle String yazma ve okuma için sorun oluşmaz. Ancak yazma işlemi farklı bir
formatta yapılmışsa bu durumda okuma işleminin de yukarıdaki örneklerde olduğu gibi byte dizisi kullanılması
gerekebilir. Bu durum genel olarak ikili (binary) dosyalar için geçerlidir
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
DataOutputStream sınıfı:
Bu durumda, DataOutputStream sınıfının writeXXX metotları temel türleri dosyaya yazılabilir. DataOutputStream
sınıfının bir başlangıç metodu vardır. Bu metot OutputStream referansı alır. Bu sınıfın writeXXX metotları yazdığı
türü byte dizisine çevirerek OutputStream referansının gösterdiği nesne için write metodunu çağırır. Böylelike
programcı herhangi bir işlem yapmadan doğrudan istediği temel türü yazabilir
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
DataOutputStream sınıfı
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.Random;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 2) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(args[0], true)) {
Random r = new Random();
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
int count = Integer.parseInt(args[1]);
for (int i = 0; i < count; ++i) {
int val = r.nextInt(100);
System.out.printf("%d ", val);
dataOutputStream.writeInt(val);
}
System.out.println();
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
DataInputStream sınıfı:
DataInputStream sınıfı da DataOutputStream sınıfıyla çok benzer biçimde kullanılmaktadır. Bu sınıf da bizden bir
InputStream parametresi alır. Sınıfın readXXX isminde metotları vardır. Bu metotlar önce bizim verdiğimiz stream’den
okumayı yaparlar. Sonra da byte dizisini ilgili türe çevirerek geri döndürürler. readXXX metotları dosya (stream)
sonuna gelindiğinde EOFException nesnesi fırlatırlar
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
DataInputStream sınıfı
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileInputStream fileInputStream = new FileInputStream(args[0])) {
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
for (;;) {
int val = dataInputStream.readInt();
System.out.printf("%d ", val);
}
}
catch (EOFException ex) {
System.out.println("\nOkuma tamamlandı");
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
DataOutputStream sınıfının writeUTF metodu UTF-8 formatında yazıyı dosyaya (stream'e) yazar. Şüphesiz yazının
uzunluğu gibi bilgileri kendi içerisinde ayarlar. Yani formatı ona göre oluşturur
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(args[0], true)) {
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
dataOutputStream.writeUTF(text);
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
DataInputStream sınıfının readUTF metodu UTF-8 formatında bilgiyi dosyadan (stream'den) okur. Bu metot da dosya
sonuna gelindiğinde EOFException fırlatır
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileInputStream fileInputStream = new FileInputStream(args[0])) {
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
for (;;) {
String text = dataInputStream.readUTF();
System.out.println(text);
}
}
catch (EOFException ex) {
System.out.println("\nOkuma tamamlandı");
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
DataOutputStream sınıfında bir yazıyı dosyaya (stream'e yazan) writeBytes ve writeChar metotları da bulunmaktadır.
writeBytes metodu her bir karakteri writeByte metoduyla yazar yani 1(bir) byte olarak yazar. Bu durumda birden fazla
byte ile tutulan karakterler için okumada exception oluşabilir. Çünkü readByte metoduyla 1 byte okunur ve exception
oluşabilir. Aşağıdaki WriterApp örneğinde dosyaya Türkçe karakterlerden oluşan yazılar ekleyiniz ve ReaderApp ile
okuma sonucu gözlemleyiniz
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
WriterApp
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(args[0], true)) {
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
dataOutputStream.writeBytes(text + '\n');
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
ReaderApp
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (FileInputStream fileInputStream = new FileInputStream(args[0])) {
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
for (;;) {
byte ch = dataInputStream.readByte();
System.out.printf("%c", (byte)ch);
}
}
catch (EOFException ex) {
System.out.println("\nOkuma tamamlandı");
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
BufferedReader ve BufferedWriter Sınıfları
BufferedReader ve BufferedWriter sınıfları yazıyla işlem yapan adaptör sınıflardır. Bu sınıfları DataOutputStream
ve DataInputStream sınıflarının yazı ile işlem yapan biçimlerine benzetebiliriz. BufferedReader ve BufferedWriter
sınıfları sırasıyla Reader ve Writer türden referansını parametre olarak bizden alırlar. BufferedWriter sınıfının
write metotları yazdırma işlemini yapmaktadır. Bu durumda dosyayı bir editörle açtığımızda anlamlı şeyler görürürüz.
Pekiyi DataOutputStream sınıfı ile BufferedWriter sınıfı arasındaki temel fark nedir? DataOutputStream sınıfı
bilgiyi byte dizisine dönüştürüp dosyaya yazar. Halbuki BufferedWriter sınıfı bilgiyi bir yazı olarak dosyaya yaza.
BufferedWriter ve BufferedReader sınıfları da yine sadece dosya için değil genel olarak kullanılabilen sınıflardır.
Anahtar Notlar: Bu sınıflar "tamponlu (buffered)" olarak çalışırlar. Bilginin yazılması hemnen gerçekleşmeyebilir.
Bu sebeple programcının yazmanın yapılması durumuna göre kod yazması veya basit olarak yazma işleminin tampondan
dosyaya (stream'e) hemen yazılması için de flush isimli metodu çağırması gerekir. DataOutputStream sınıfının da
flush isimli bir metodu vardır. Dosya işlemlerinde kullanılması gerekmez. Ancak BufferedWriter için dosya
işlemlerinde de gerekir. Tamponlu çalışma konusu ayrıntılı bir konudur. Burada detaylar ele alınmayacaktır.
Daha önce anlatıldığı gibi satır kavramı özellike Windows sistemleri için farklıdır. Yani bir sonraki satırın başına
geçmek için windows'da "CRLF" karakter çiftinin kullanıldığını hatırlayınız. Bu sebeple işletim sistemine göre uygun
satır sonu karakter veya karakterlerinin yazılması için BufferedWriter sınıfının newLine isimli metodu kullanılır.
BufferedReader ve BufferedWriter sınıfları Closable arayüzünü destekler
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
BufferedWriter sınıfının dosya işlemlerinde kullanımında nesne yaratmak için FileWriter isimli yine
adaptör bir sınıf Write parametreli ctor'u için kullanılabilir. Dosyalar için genel kalıp aşağıdaki
gibidir. FileWriter'a charset verilmezse default charset kullanılır
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.*;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(args[0], true))) {
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
bufferedWriter.write(text);
bufferedWriter.newLine();
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
BufferedReader sınıfının dosya işlemlerinde kullanımında nesne yaratmak için FileReader isimli yine
adaptör bir sınıf Reader parametreli ctor'u için kullanılabilir. Dosyalar için genel kalıp aşağıdaki
gibidir. FileReader'a charset verilmezse default charset kullanılır. Satır satır okuma yapmak için readLine metodu
kullanılır. readLine metodu dosya sonuna gelindiğinde null döndürür
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.*;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(args[0]))) {
String line;
while ((line = bufferedReader.readLine()) != null)
System.out.println(line);
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Yukarıdaki örneğin kesin UTF-8 ile çalışan versiyonu
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(args[0], StandardCharsets.UTF_8, true))) {
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
bufferedWriter.write(text);
bufferedWriter.newLine();
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Yukarıdaki örneğin kesin UTF-8 ile çalışan versiyonu
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(args[0], StandardCharsets.UTF_8))) {
String line;
while ((line = bufferedReader.readLine()) != null)
System.out.println(line);
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Klavye işlemleri için BufferedReader aşağıdaki gibi kullanılabilir. Sınıfın metotlarının IOException fırlattığına
dikkat ediniz
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
class App {
public static void main(String[] args) throws IOException
{
BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
for (;;) {
System.out.print("Bir yazı giriniz:");
String str = kb.readLine();
byte[] data = str.getBytes(StandardCharsets.UTF_8);
System.out.printf("Byte length of %s:%d%n", str, data.length);
if (str.equals("quit"))
break;
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Yukarıdaki örnek Files sınıfının newBufferedWriter metodu ile de yapılabilir
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Scanner;
class WriterApp {
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Path.of(args[0]), StandardCharsets.UTF_8, StandardOpenOption.APPEND, StandardOpenOption.CREATE)) {
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = kb.nextLine();
if (text.equals("quit"))
break;
bufferedWriter.write(text);
bufferedWriter.newLine();
}
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Yukarıdaki örnek Files sınıfının newBufferedReader metodu ile de yapılabilir
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;
class ReaderApp {
public static void main(String[] args)
{
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", new Scanner(System.in));
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of(args[0]), StandardCharsets.UTF_8)) {
String line;
while ((line = bufferedReader.readLine()) != null)
System.out.println(line);
}
catch (FileNotFoundException ex) {
System.out.println("Dosya bulunamadı");
System.out.printf("Message:%s%n", ex.getMessage());
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
RandomAccessFile Sınıfı
RandomAccessFile sınıfı ile dosya üzerinde istenilen offset’e konumlanma yapılarak yazma ya da okuma yapılabilir.
RandomAccessFile sınıfı ile dosyanın açılış moduna göre okuma veya hem okuma hem yazma yapılabilir. RandomAccessFile
Object sınıfından türetilmiştir. Closeable arayüzünü ve diğer bazı okuma ve yazmaya ilişkin arayüzleri
desteklemektedir. Sınfın write ve writeXXX metotları ile yazma işlemi yapılabilir. read ve readXXX metotları ile de
okuma yapılabilir. Sınıfın iki adet başlangıç metodu bulunmaktadır. Başlangıç metotlarının birinci parametreleri
dosyaya ilişkin isim ya da File referansıdır. Başlangıç metotlarının ikinci parametreleri ortaktır. Bu parametreler
dosyanın açılış modunu belirlemek için kullanılır. Açılış modları “r”, “rw”, “rws”, “rwd” biçiminde olabilir.
Bunlar dışındaki değerler exception oluşmasına yol açar:
“r” → Yalnızca okuma amaçlı açmak için kullanılır. Dosya yoksa exception oluşur.
“rw” → Hem okuma hem de yazma amaçlı kullanılan moddur. Dosya yoksa yaratılır.
“rws” ve “rwd” açılış modları “New IO” mekanizmasına ilişkindir. Burada ele alınmayacaktır
RandomAccessFile sınıfı dosyayı her zaman korur. RandomAccessFile sınıfı ile dosya açıldığında dosya göstericisi
sıfır numaralı offet'i gösterir.
Dosya Göstericisinin Konumlandırılması
Sınfın seek metodu ile istenilen bir offsete konumlanılabilir. Sınıfın getFilePointer metodu ile o anki dosya
göstericisinin nerede olduğu bilgisi alınabilir.
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
RandomAccessFile sınıfı ile basit bir örnek. Örnekte hem dosyaya yazma hem de dosyadan okuma yapılmıştır
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
class App {
public static void main(String[] args) throws IOException
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
try (RandomAccessFileStandartInputApp randomAccessFileStandartInputApp = new RandomAccessFileStandartInputApp(args[0], kb)) {
randomAccessFileStandartInputApp.run();
}
catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
class RandomAccessFileStandartInputApp implements Closeable {
private final RandomAccessFile m_randomAccessFile;
private final Scanner m_kb;
private void runForWrite() throws IOException
{
for (;;) {
System.out.print("Bir yazı giriniz:");
String text = m_kb.nextLine();
if (text.equals("quit"))
break;
m_randomAccessFile.writeUTF(text);
}
System.out.printf("Offset of File Pointer:%d%n", m_randomAccessFile.getFilePointer());
}
private void runForRead() throws IOException
{
m_randomAccessFile.seek(0); //Dosya göstericisini dosyanın başına konumlandırdık
try {
for (;;) {
String text = m_randomAccessFile.readUTF();
System.out.printf("%s ", text);
}
}
catch (EOFException ex) {
System.out.println();
}
}
public RandomAccessFileStandartInputApp(String path) throws IOException
{
this(path, new Scanner(System.in));
}
public RandomAccessFileStandartInputApp(String path, Scanner kb) throws IOException
{
m_randomAccessFile = new RandomAccessFile(path, "rw");
m_randomAccessFile.seek(m_randomAccessFile.length()); //Dosya göstericisini dosyanın sonuna konumlandırdık
m_kb = kb;
}
public void run() throws IOException
{
this.runForWrite();
this.runForRead();
}
public void close() throws IOException
{
m_randomAccessFile.close();
}
}
/*----------------------------------------------------------------------------------------------------------------------
Endian kavramı: Birden fazla byte'dan oluşan değerlerin bellekte tutuluşları sistemden sisteme değişebilmektedir.
Pratikte iki yerleşim biçimi kullanılmaktadır:
1. Düşük anlamlı byte değerlerinin ona ayrılan belleğin düşük sayısal adresinde bulunacak biçimde yerleştirilmesine
"little endian" denir.
2. Düşük anlamlı byte değerlerinin ona ayrılan belleğin yüksek sayısal adresinde bulunacak biçimde yerleştirilmesine
"big endian" denir.
Endian kavramı tamsayılar için kullanılır. Gerçek sayı türleri için IEEE 754 standartlarında endian kavramı
belirtilmemiştir. Teorik olarak gerçek sayılar için endian değişebilse de pratikte bu durum bir sorun oluşturmaz.
Java'da tamsayı türleri sistemden bağımsız olarak "big endian" kullanılır
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
Çalışılan sistemin endian'ının anlaşılması
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import package org.csystem.util;
import java.io.IOException;
import java.nio.ByteOrder;
class App {
public static void main(String[] args) throws IOException
{
System.out.printf("Your system is %s%n", SystemUtil.getEndianText());
}
}
/*----------------------------------------------------------------------------------------------------------------------
ByteBuffer nesnesinin endian çalışma bilgisinin değiştirilmesi
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.SystemUtil;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Scanner;
class App {
public static void main(String[] args) throws IOException
{
Scanner kb = new Scanner(System.in);
System.out.print("Bir sayı giriniz:");
short val = Short.parseShort(kb.nextLine());
ByteBuffer byteBuffer = ByteBuffer.allocate(4).putShort(val);
System.out.println(SystemUtil.getEndian(byteBuffer));
SystemUtil.toLittleEndian(byteBuffer);
System.out.println(SystemUtil.getEndian(byteBuffer));
val = byteBuffer.getShort(0);
System.out.printf("val:%d%n", val);
}
}
/*----------------------------------------------------------------------------------------------------------------------
Sınıf Çalışması: Standart cihaz bağımsız bitmap (Device Independent Bitmap) dosyasında resmin genişliği ve uzunluğu
dosyanın başından itibaren 18'inci ve 22'inci offsetlerde int bir bilgi olarak tutulmaktadır. Formata göre bu bilgi
"little endian" olarak yazılmıştır. Bu bilgiyi bir resim dosyasından alıp ekrana yazdıran programı yazınız. Program
resmin geçerliliği gibi detaylı kontrolleri yapmayacaktır.
Program açıklayıcı olması açısından sadece main içerisinde yazılmıştır
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.util.CommanLineUtil;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Scanner;
class App {
public static void main(String[] args) throws IOException
{
Scanner kb = new Scanner(System.in);
args = CommanLineUtil.getArguments(args, "Yol ifadesini giriniz", kb);
if (args.length != 1) {
System.out.println("Wrong usage");
System.exit(-1);
}
byte [] data = new byte[4];
try (RandomAccessFile randomAccessFile = new RandomAccessFile(args[0], "r")) {
randomAccessFile.seek(18);
randomAccessFile.read(data);
int width = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getInt();
randomAccessFile.read(data);
int height = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.printf("%d x %d%n", width, height);
}
catch (Throwable ex) {
System.out.println(ex.getMessage());
}
}
}
/*----------------------------------------------------------------------------------------------------------------------
Sınıf Çalışması: Aşağıdaki açıklanan programı yazınız:
- Program içerisinde bir menü olacaktır
- Menüler sırasıyla "Ekle", "Listele" ve çıkış şeklindedir
- Cihazlara ilişkin bilgiler (id, name, host) devices.dat isimli bir dosyada saklanacaktır
- Dosya programın sonuna kadar açık kalacaktır
- Örnek basit olması açısından dosya formatı kontrolü yapılmamıştır
- Fonksiyonel programlama kullanılarak daha iyi şekilde yazılabilir (Uygulama kursunda ele alınacaktır)
- TODO: Dosyanın sürekli açık kalmayan versiyonunu yazınız
- Dosya kapatım
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.app;
import org.csystem.app.samples.devicesapp.DevicesPersistenceApp;
class App {
public static void main(String[] args)
{
DevicesPersistenceApp.run();
}
}
package org.csystem.app.samples.devicesapp;
public final class DevicesPersistenceApp {
private DevicesPersistenceApp()
{
}
public static void run()
{
try (DevicesPersistence devicesPersistence = new DevicesPersistence("devices.dat")) {
devicesPersistence.run();
}
catch (Throwable ex) {
System.out.println("Beklenmedik bir durum oluştu. Uygulama sonlanıyor...");
}
}
}
package org.csystem.app.samples.devicesapp;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
public class DevicesPersistence implements Closeable {
private final Scanner m_kb = new Scanner(System.in);
private final RandomAccessFile m_randomAccessFile;
private void displayMenu()
{
System.out.println("1.Ekle");
System.out.println("2.Listele");
System.out.println("3.Çıkış");
System.out.print("Seçenek:");
}
private void insertProc() throws IOException
{
System.out.print("id değerini giriniz:");
int id = Integer.parseInt(m_kb.nextLine());
System.out.print("Adını giriniz:");
String name = m_kb.nextLine();
System.out.print("Ip adresini giriniz:");
String host = m_kb.nextLine();
m_randomAccessFile.seek(m_randomAccessFile.length());
m_randomAccessFile.writeInt(id);
m_randomAccessFile.writeUTF(name);
m_randomAccessFile.writeUTF(host);
}
private void listProc() throws IOException
{
try {
m_randomAccessFile.seek(0);
for (;;) {
int id = m_randomAccessFile.readInt();
String name = m_randomAccessFile.readUTF();
String host = m_randomAccessFile.readUTF();
System.out.printf("[%d]%s-%s%n", id, name, host);
}
}
catch (EOFException ex) {
System.out.println("Okuma tamamlandı");
}
}
private void exitProc()
{
System.out.println("C ve Sistem Programsıları Derneği");
System.out.println("Tekrar yapıyor musunuz?");
System.exit(0);
}
private void doWorkForOption(int option) throws IOException
{
switch (option) {
case 1:
this.insertProc();
break;
case 2:
listProc();
break;
case 3:
exitProc();
break;
default:
System.out.println("Geçersiz seçenek");
}
}
public DevicesPersistence(String path) throws IOException
{
m_randomAccessFile = new RandomAccessFile(path, "rw");
}
public void run()
{
for (;;) {
try {
this.displayMenu();
this.doWorkForOption(Integer.parseInt(m_kb.nextLine()));
}
catch (NumberFormatException ex) {
System.out.println("Geçersiz giriş");
}
catch (Throwable ex) {
System.out.println("Beklenmedik bir durum oluştu");
}
}
}
public void close() throws IOException
{
m_randomAccessFile.close();
}
}
/*----------------------------------------------------------------------------------------------------------------------
Dosyalar ve genel olarak giriş/çıkış işlemleri için Java'da daha başka sınıflar da vardır. Burada dosya işlemlerine
yönelik temel olan sınıflar anlatılmıştır
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
CommandLineUtil sınıfı
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.util;
import java.util.Scanner;
public final class CommanLineUtil {
private CommanLineUtil()
{}
public static String [] getArguments(String [] args, String prompt, Scanner scanner)
{
if (args.length > 0)
return args;
System.out.print(prompt + ":");
return scanner.nextLine().split("[ \t]+");
}
}
/*----------------------------------------------------------------------------------------------------------------------
SystemUtil sınıfı
----------------------------------------------------------------------------------------------------------------------*/
package org.csystem.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public final class SystemUtil {
private SystemUtil()
{
}
public static String getEndianText()
{
return isLittleEndian() ? "LITTLE ENDIAN" : "BIG ENDIAN";
}
public static ByteOrder getEndian(ByteBuffer byteBuffer)
{
return byteBuffer.order();
}
public static void toLittleEndian(ByteBuffer byteBuffer)
{
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
public static void toBigEndian(ByteBuffer byteBuffer)
{
byteBuffer.order(ByteOrder.BIG_ENDIAN);
}
public static boolean isLittleEndian()
{
return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
}
}
/*----------------------------------------------------------------------
FILE : BitConverter.java
AUTHOR : Oğuz Karan
LAST UPDATE : 05.10.2020
BitConverter class for byte operations with built-in types
Copyleft (c) 1993 by C and System Programmers Association (CSD)
All Rights Free
-----------------------------------------------------------------------*/
package org.csystem.util.converter;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public final class BitConverter {
private static ByteBuffer allocate(int capacity)
{
return ByteBuffer.allocate(capacity);
}
private static ByteBuffer wrap(byte [] data, int offset, int length)
{
return ByteBuffer.wrap(data, offset, length);
}
private BitConverter()
{
}
public static byte [] getBytes(String str)
{
return getBytes(str, StandardCharsets.UTF_8);
}
public static byte [] getBytes(String str, Charset charset)
{
return str.getBytes(charset);
}
public static byte [] getBytes(byte value)
{
return new byte [] {value};
}
public static byte[] getBytes(short value)
{
return allocate(2).putShort(value).array();
}
public static byte[] getBytes(int value)
{
return allocate(4).putInt(value).array();
}
public static byte[] getBytes(long value)
{
return allocate(8).putLong(value).array();
}
public static byte[] getBytes(char value)
{
return allocate(2).putChar(value).array();
}
public static byte[] getBytes(double value)
{
return allocate(8).putDouble(value).array();
}
public static byte[] getBytes(float value)
{
return allocate(4).putFloat(value).array();
}
public static byte[] getBytes(boolean value)
{
return new byte[] {(byte)(value ? 1 : 0)};
}
public static String toString(byte [] data)
{
return toString(data, StandardCharsets.UTF_8);
}
public static String toString(byte [] data, Charset charset)
{
return new String(data, charset);
}
public static short toShort(byte [] data)
{
return toShort(data, 0);
}
public static short toShort(byte [] data, int startIndex)
{
return wrap(data, startIndex, 2).getShort();
}
public static int toInt(byte [] data)
{
return toInt(data, 0);
}
public static int toInt(byte [] data, int startIndex)
{
return wrap(data, startIndex, 4).getInt();
}
public static long toLong(byte [] data)
{
return toLong(data, 0);
}
public static long toLong(byte [] data, int startIndex)
{
return wrap(data, startIndex, 8).getLong();
}
public static char toChar(byte [] data)
{
return toChar(data, 0);
}
public static char toChar(byte [] data, int startIndex)
{
return wrap(data, startIndex, 2).getChar();
}
public static double toDouble(byte [] data)
{
return toDouble(data, 0);
}
public static double toDouble(byte [] data, int startIndex)
{
return wrap(data, startIndex, 8).getDouble();
}
public static float toFloat(byte [] data)
{
return toFloat(data, 0);
}
public static float toFloat(byte [] data, int startIndex)
{
return wrap(data, startIndex, 4).getFloat();
}
public static boolean toBoolean(byte [] data)
{
return toBoolean(data, 0);
}
public static boolean toBoolean(byte [] data, int startIndex)
{
return data[startIndex] != 0;
}
}
/*----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------*/