Bölüm 7: Giriş Çıkış

Bölüm 7: Giriş Çıkış · Çalışma Soruları
AkışlarKodlamaFileMetin okuma ve yazmaTamponlamaBayt akışlarıKopyalamaRastgele erişimSerileştirmeNIO
Sercan KÜLCÜ

Çoktan Seçmeli · Akışlar

Soru 1: Çıktıyı Dosyaya Yönlendirmek

Program hem System.out.println("sonuç") hem de System.err.println("uyarı") çalıştırıyor ve komut satırından java Uygulama > sonuc.txt ile başlatılıyor. Hangisi doğrudur?

C: > yalnızca standart çıktıyı (System.out) dosyaya yönlendirir. System.err ayrı bir akıştır ve ekranda kalır; hata iletileri bu sayede çıktı dosyasına karışmaz ve gözden kaçmaz.

Çıktı Sorusu · Akışlar

Soru 2: nextInt'ten Sonra nextLine

Klavye girdisinin yerine aynı metni okuyan bir Scanner kullanılıyor. Program ne yazdırır?

Scanner sc = new Scanner("19\nAyşe Yılmaz\n");
int yas = sc.nextInt();
String ad = sc.nextLine();
System.out.println("[" + ad + "] " + yas);
System.out.println("[" + sc.nextLine() + "]");
Cevabı göster
[] 19
[Ayşe Yılmaz]

nextInt() yalnızca 19 rakamlarını okur; satır sonu (⏎) okunmadan kalır. İlk nextLine() bu satır sonuna kadar olan boş metni alır: ad = "". Asıl isim ikinci nextLine() ile gelir.

Düzeltme: nextInt()'ten sonra satır sonunu atmak için bir sc.nextLine(); çağırmak ya da sayıyı Integer.parseInt(sc.nextLine()) ile okumak.

Çoktan Seçmeli · Dosyalar ve Kodlama

Soru 3: Kaç Bayt?

"Çağrı" dizgisi (5 karakter) bir metin dosyasına UTF-8 kodlamasıyla yazılıyor. Dosya kaç bayt olur?

B: UTF-8, ASCII karakterlerini (a, r) 1 baytta, Türkçe harfleri (Ç, ğ, ı) 2 baytta yazar: 2 + 1 + 2 + 1 + 2 = 8. 5 bayt ISO-8859-9 (Latin-5) ile, 10 bayt UTF-16 ile kaydedilen dosyanın boyutudur. "Çağrı".getBytes(StandardCharsets.UTF_8).length de 8 verir.

Çıktı Sorusu · Dosyalar ve Kodlama

Soru 4: char ve Kod Değeri

Program hangi altı satırı yazdırır?

char c = 'a';
c += 2;
System.out.println(c);
System.out.println('a' + 2);
System.out.println((char) ('A' + 32));
System.out.println('9' - '0' + 1);
System.out.println("" + 'x' + 1);
System.out.println('x' + 1 + "");
Cevabı göster
c
99
a
10
x1
121
  • c += 2: bileşik atama sonucu yine char'a çevirir: 97 + 2 = 99 → 'c'.
  • 'a' + 2: char + int işlemi int üretir: 99.
  • 'A' + 32 = 97, (char) ile 'a'. Büyük ve küçük harf arasındaki fark 32'dir.
  • '9' - '0' = 57 − 48 = 9, artı 1: 10.
  • "" + 'x' + 1 soldan sağa dizgi birleştirmedir: "x1"; 'x' + 1 + "" önce sayı toplar: 120 + 1 = 121.

Çıktı Sorusu · Dosyalar ve Kodlama

Soru 5: Metin ve İkili Boyut

Aynı değerler önce metin, sonra ikili olarak yazılıyor. Program hangi iki sayıyı yazdırır?

try (PrintWriter pw = new PrintWriter("m.txt")) {
  pw.print(-15);
  pw.print(3.5);
}
System.out.println(new File("m.txt").length());
try (DataOutputStream d = new DataOutputStream(
    new FileOutputStream("m.dat"))) {
  d.writeShort(-15);
  d.writeDouble(3.5);
  d.writeBoolean(true);
}
System.out.println(new File("m.dat").length());
Cevabı göster
6
11

Metin: print(-15) ve print(3.5) karakterleri yan yana yazar: "-153.5", 6 karakter, ASCII ile 6 bayt.

İkili: writeShort 2, writeDouble 8, writeBoolean 1 bayt yazar: 2 + 8 + 1 = 11. İkili dosyada boyut değerin basamak sayısına değil, tipine bağlıdır; ama değerler yalnızca aynı sırayla (readShort, readDouble, readBoolean) doğru geri okunur.

Çoktan Seçmeli · Dosya Sistemi

Soru 6: Olmayan Dosya için File

Diskte yok.txt adlı bir dosya yokken File f = new File("yok.txt"); çalıştırılıyor. Hangisi doğrudur?

D: File yalnızca bir yolu temsil eder; diske dokunmaz, istisna fırlatmaz. Olmayan dosya için exists() false, length() 0 döner. Dosya oluşturmak için createNewFile() ya da bir yazma akışı gerekir; FileNotFoundException ise dosyayı okumak için akış açarken (new FileReader(f)) gelir.

Çıktı Sorusu · Metin Okuma ve Yazma

Soru 7: Yazma, Ekleme, Satır Sayma

g.txt başta yok. Program ne yazdırır?

try (FileWriter w = new FileWriter("g.txt")) {
  w.write("bir\niki\n");
}
try (FileWriter w = new FileWriter("g.txt", true)) {
  w.write("üç");
}
try (FileWriter w = new FileWriter("g.txt", true)) {
  w.write("dört\n");
}
int n = 0;
String son = null;
try (BufferedReader r = new BufferedReader(
    new FileReader("g.txt"))) {
  String s;
  while ((s = r.readLine()) != null) {
    n++;
    son = s;
  }
}
System.out.println(n + " " + son);
Cevabı göster
3 üçdört

Birinci yazıcı dosyayı oluşturur: bir⏎iki⏎. İkinci ve üçüncü true ile sona ekler; "üç" satır sonu içermediği için "dört" aynı satıra yapışır: bir⏎iki⏎üçdört⏎.

readLine() üç satır okur, satır sonlarını atar; dördüncü çağrı null döndürür. true verilmeseydi her yazıcı dosyayı sıfırlardı.

Kod Yazma · Metin Okuma ve Yazma

Soru 8: Not Dosyasını İşlemek

notlar.txt dosyasının her satırında bir ad ve bir tam sayı not var (ör. Ali 70, Ayşe 85, Can 90). Dosyayı Scanner ile okuyup kişi sayısını ve not ortalamasını yazdıran kodu yazın; dosya yoksa hata iletisi yazılsın, Scanner her durumda kapansın.

Cevabı göster
int toplam = 0, adet = 0;
try (Scanner f = new Scanner(new File("notlar.txt"))) {
  while (f.hasNext()) {
    f.next();                 // ad
    toplam += f.nextInt();    // not
    adet++;
  }
  System.out.println(adet + " kişi, ortalama "
      + (double) toplam / adet);
} catch (FileNotFoundException e) {
  System.err.println("Dosya yok: " + e.getMessage());
}

Örnek dosya için çıktı: 3 kişi, ortalama 81.66666666666667. try-with-resources Scanner'ı hata olsa da kapatır; (double) dönüşümü tam sayı bölmesini önler. next() boşluğa kadar bir kelime, nextInt() bir sayı okur.

Çoktan Seçmeli · Tamponlama

Soru 9: Tampon Kaç Kez Dolar?

2 MB'lık (2 097 152 bayt) bir dosya new BufferedInputStream(new FileInputStream(f)) ile read() çağrılarak bayt bayt okunuyor. Tampon 8192 bayttır. Veri, alttaki FileInputStream'den kaç okuma çağrısıyla gelir?

A: Tampon boşaldıkça alttaki akıştan bir seferde 8192 bayt ister: 2 097 152 / 8192 = 256 veri taşıyan okuma (sonda bir de −1 döndüren çağrı). Programın 2 097 152 read() çağrısı bellekteki tampondan karşılanır. Tamponsuz akışta her read() bir sistem çağrısı olurdu.

Çoktan Seçmeli · Diğer Bayt Akışları

Soru 10: read() Sonucunu byte'ta Tutmak

Bu döngü kaç bayt işler?

InputStream in = new ByteArrayInputStream(
    new byte[] {65, (byte) 255, 66});
byte b;
int islenen = 0;
while ((b = (byte) in.read()) != -1) {
  islenen++;
}
System.out.println(islenen);

B: İlk bayt 65 işlenir. İkinci read() 255 döndürür; (byte) dönüşümü bunu −1 yapar ve döngü dosya sonu sanıp durur. Üçüncü bayt hiç okunmaz. Bu yüzden read() sonucu int bir değişkende tutulur: veri 0–255, dosya sonu −1 olarak ayrışır.

Adım Adım Çalıştırma · Diğer Bayt Akışları

Soru 11: read(byte[]) ve Eski Baytlar

Bellekteki 7 baytlık kaynak 3 baytlık bir diziyle okunuyor. Program ne yazdırır?

kaynak (7 bayt)J0A1V2A3-4I5O6dizi012

Kaynak 7 bayt: J, A, V, A, -, I, O. Akış baştan okunacak.

kaynak (7 bayt)J0A1V2A3-4I5O6dizi000102

3 hücrelik dizi sıfırlarla oluşur.

kaynak (7 bayt)J0A1V2A3-4I5O6diziJ0A1V2

read(dizi) en çok 3 bayt okur: J, A, V. Dönen değer 3.

kaynak (7 bayt)J0A1V2A3-4I5O6diziJ0A1V2

new String(dizi) dizinin tamamını çevirir: JAV.

kaynak (7 bayt)J0A1V2A3-4I5O6diziA0-1I2

Sonraki 3 bayt aynı dizinin üzerine yazılır: A, -, I.

kaynak (7 bayt)J0A1V2A3-4I5O6diziA0-1I2

İkinci satır: A-I.

kaynak (7 bayt)J0A1V2A3-4I5O6diziO0-1I2

Yalnızca 1 bayt kaldı: dizi[0] = O olur; dizi[1] ve dizi[2] önceki turdan kalan - ve I'dır.

kaynak (7 bayt)J0A1V2A3-4I5O6diziO0-1I2

Hata görünür oldu: k = 1 olduğu hâlde 3 bayt çevrildi, O-I yazıldı. Doğrusu new String(dizi, 0, k): yalnızca O.

kaynak (7 bayt)J0A1V2A3-4I5O6diziO0-1I2

Kaynak bitti: read −1 döndürür, döngü biter. Aynı hata kopyalamada write(dizi) yazılırsa kopyayı büyütür; write(dizi, 0, k) gerekir.

byte[] kaynak = "JAVA-IO".getBytes();
InputStream in = new ByteArrayInputStream(kaynak);
byte[] dizi = new byte[3];
int k;
while ((k = in.read(dizi)) != -1) {
  System.out.println(k + " " + new String(dizi));
}

Çoktan Seçmeli · Dosya Kopyalama

Soru 12: Hedef Dosya Zaten Varsa

k2.txt zaten varken Files.copy(Paths.get("k1.txt"), Paths.get("k2.txt")); çağrılıyor. Ne olur?

C: Files.copy var olan hedefin üzerine kendiliğinden yazmaz; java.nio.file.FileAlreadyExistsException: k2.txt fırlatır. Üzerine yazmak için üçüncü argüman StandardCopyOption.REPLACE_EXISTING verilir. Sona ekleme FileWriter(ad, true) ya da StandardOpenOption.APPEND ile yapılır.

Kod Yazma · Dosya Kopyalama

Soru 13: Blok Blok Kopyalama Metodu

static long kopyala(String kaynak, String hedef) throws IOException metodunu yazın: her tür dosyayı 4 KB'lık parçalar hâlinde, tamponlu akışlarla kopyalasın, akışları her durumda kapatsın ve kopyalanan bayt sayısını döndürsün.

Cevabı göster
static long kopyala(String kaynak, String hedef)
    throws IOException {
  byte[] parca = new byte[4096];
  long toplam = 0;
  try (InputStream in = new BufferedInputStream(
           new FileInputStream(kaynak));
       OutputStream out = new BufferedOutputStream(
           new FileOutputStream(hedef))) {
    int n;
    while ((n = in.read(parca)) != -1) {
      out.write(parca, 0, n);   // yalnızca okunan n bayt
      toplam += n;
    }
  }
  return toplam;
}

10 000 baytlık rastgele bir dosyayla denendi: 10000 döndü, kopya bayt bayt aynıydı. Bayt akışı kullanıldığı için resim, .class gibi ikili dosyalar da bozulmaz; karakter akışı (FileReader) ikili veriyi bozabilir. Kaynaklar ters sırada kapanır, out kapanırken tamponunu diske boşaltır.

Adım Adım Çalıştırma · Rastgele Erişim

Soru 14: RandomAccessFile ile Kayıtlar

r.dat başta yok. Her int 4 bayttır. Program ne yazdırır?

0481216işaretçi 0

"rw": dosya yoksa oluşturulur; işaretçi 0'da.

50104158201216işaretçi 16

Dört writeInt: 5, 10, 15, 20. Her biri 4 bayt yazar, işaretçi 16'ya ilerler.

50104158201216işaretçi 12

seek(8): 3. kaydın başı. readInt 8–11. baytları okur: 15; işaretçi 12.

50104158201216işaretçi 12

Okunan değer ve işaretçi yazdırılır.

50994158201216işaretçi 8

seek(4) ve writeInt(99): 2. kayıt yerinde değişir (10 → 99); dosyanın geri kalanı aynı kalır.

509941582012251620işaretçi 20

seek(length()) dosya sonuna gider; writeInt(25) dosyayı 20 bayta büyütür.

509941582012251620işaretçi 20

Uzunluk 20, işaretçi de 20 (dosya sonu).

509941582012251620işaretçi 20

Başa dönülür; işaretçi uzunluğa ulaşana kadar beş int okunur: 5 + 99 + 15 + 20 + 25 = 164.

509941582012251620işaretçi 20

Toplam yazdırılır, dosya kapatılır. Akışlarla 2. kaydı yerinde değiştirmek mümkün değildi.

RandomAccessFile f = new RandomAccessFile("r.dat", "rw");
for (int i = 1; i <= 4; i++)
  f.writeInt(i * 5);
f.seek(8);
int x = f.readInt();
System.out.println(x + " " + f.getFilePointer());
f.seek(4);
f.writeInt(99);
f.seek(f.length());
f.writeInt(25);
System.out.println(f.length() + " " + f.getFilePointer());
f.seek(0);
int t = 0;
while (f.getFilePointer() < f.length())
  t += f.readInt();
System.out.println("Toplam: " + t);
f.close();

Çoktan Seçmeli · Serileştirme

Soru 15: Serileştirilemeyen Alan

Ogrenci sınıfı Serializable'dır ama Adres sınıfı değildir. cikti.writeObject(new Ogrenci()) çalıştırıldığında ne olur?

class Adres {
  String sehir = "Giresun";
}
class Ogrenci implements Serializable {
  String ad = "Ece";
  Adres adres = new Adres();
}

D: Serileştirme nesneyle birlikte alanlarının gösterdiği nesneleri de yazar; Adres işaret arayüzünü taşımadığı için çalışma zamanında java.io.NotSerializableException fırlar. Derleyici bunu denetlemez. Çözüm: Adres'i de Serializable yapmak ya da alanı transient işaretlemek (o zaman geri okununca null olur).

Çıktı Sorusu · Serileştirme

Soru 16: transient, static ve Yeni Nesne

P sınıfının nesnesi yazılıp geri okunuyor. Son satır ne yazdırır?

class P implements Serializable {
  int a = 1;
  transient int b = 2;
  static int c = 3;
}
// main içinde:
P p = new P();
p.a = 10; p.b = 20; P.c = 30;
ObjectOutputStream o = new ObjectOutputStream(
    new FileOutputStream("p.ser"));
o.writeObject(p);
o.close();
P.c = 40;
ObjectInputStream i = new ObjectInputStream(
    new FileInputStream("p.ser"));
P q = (P) i.readObject();
i.close();
System.out.println(q.a + " " + q.b + " "
    + P.c + " " + (q == p));
Cevabı göster
10 0 40 false
  • a serileştirildi: 10.
  • b transient: yazılmadı, geri okununca varsayılan değer 0 oldu. Alan ilklendiricisi (= 2) çalışmaz, çünkü readObject serileştirilebilir sınıfın yapıcısını çağırmaz.
  • c static: nesneye değil sınıfa aittir, dosyaya hiç yazılmaz; bellekteki son değer 40'tır.
  • readObject yeni bir nesne kurar: q == p false.

Çoktan Seçmeli · NIO

Soru 17: Seçici Ne İşe Yarar?

NIO seçicisi (Selector) için hangisi doğrudur?

A: Kanallar configureBlocking(false) ile bloklamayan moda alınıp register(secici, SelectionKey.OP_READ) gibi çağrılarla kaydedilir; select() en az bir kanal hazır olana kadar bekler. Böylece çok sayıda bağlantı tek iş parçacığıyla yönetilir; bağlantı başına iş parçacığı klasik akış modelidir. flip() tampona ait bir işlemdir.

Adım Adım Çalıştırma · NIO

Soru 18: ByteBuffer: flip ve compact

6 baytlık bir tamponla şu işlemler yapılıyor. Program ne yazdırır? Yeşil hücreler konum (pos) ile sınır (lim) arasıdır.

000102030405poslim

Boş tampon: yazma modunda konum 0, sınır = kapasite = 6.

1002013024030405poslim

Dört put: 10, 20, 30, 40. Her put konumu 1 ilerletir: pos 4.

1002013024030405poslim

flip(): sınır = eski konum (4), konum = 0. Okunabilir veri 0–3.

1002013024030405poslim

İki get: 10 ve 20. Okunmamış 30 ve 40 kaldı.

3004013024030405poslim

compact(): okunmamış 30, 40 başa kopyalanır; pos = kalan sayısı (2), lim = 6. 2–3'teki eski 30, 40 silinmez, üzerine yazılacak.

3004015026030405poslim

50 ve 60 konum 2 ve 3'e yazılır.

3004015026030405poslim

Yeniden okuma moduna: lim 4, pos 0. Okunacak: 30, 40, 50, 60.

3004015026030405poslim

remaining() = lim − pos = 4.

3004015026030405poslim

get() konumdakini okur (30) ve pos'u ilerletir; get(3) mutlak indisle okur (60) ve pos'a dokunmaz.

ByteBuffer b = ByteBuffer.allocate(6);
b.put((byte) 10).put((byte) 20);
b.put((byte) 30).put((byte) 40);
b.flip();
byte g1 = b.get();
byte g2 = b.get();
b.compact();
b.put((byte) 50).put((byte) 60);
b.flip();
System.out.println(g1 + " " + g2);
System.out.println(b.position() + " "
    + b.limit() + " " + b.remaining());
System.out.println(b.get() + " " + b.get(3));

Son

Bölüm 7: Giriş Çıkış: Çalışma Soruları
Konu anlatımı: Giriş çıkış sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.