Bölüm 7: Giriş Çıkış
Ç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 yinechar'a çevirir: 97 + 2 = 99 →'c'.'a' + 2:char + intişlemiintü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' + 1soldan 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: J, A, V, A, -, I, O. Akış baştan okunacak.
3 hücrelik dizi sıfırlarla oluşur.
read(dizi) en çok 3 bayt okur: J, A, V. Dönen değer 3.
new String(dizi) dizinin tamamını çevirir: JAV.
Sonraki 3 bayt aynı dizinin üzerine yazılır: A, -, I.
İkinci satır: A-I.
Yalnızca 1 bayt kaldı: dizi[0] = O olur; dizi[1] ve dizi[2] önceki turdan kalan - ve I'dır.
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 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?
"rw": dosya yoksa oluşturulur; işaretçi 0'da.
Dört writeInt: 5, 10, 15, 20. Her biri 4 bayt yazar, işaretçi 16'ya ilerler.
seek(8): 3. kaydın başı. readInt 8–11. baytları okur: 15; işaretçi 12.
Okunan değer ve işaretçi yazdırılır.
seek(4) ve writeInt(99): 2. kayıt yerinde değişir (10 → 99); dosyanın geri kalanı aynı kalır.
seek(length()) dosya sonuna gider; writeInt(25) dosyayı 20 bayta büyütür.
Uzunluk 20, işaretçi de 20 (dosya sonu).
Başa dönülür; işaretçi uzunluğa ulaşana kadar beş int okunur: 5 + 99 + 15 + 20 + 25 = 164.
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
aserileştirildi: 10.btransient: yazılmadı, geri okununca varsayılan değer 0 oldu. Alan ilklendiricisi (= 2) çalışmaz, çünküreadObjectserileştirilebilir sınıfın yapıcısını çağırmaz.cstatic: nesneye değil sınıfa aittir, dosyaya hiç yazılmaz; bellekteki son değer 40'tır.readObjectyeni bir nesne kurar:q == pfalse.
Ç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.
Boş tampon: yazma modunda konum 0, sınır = kapasite = 6.
Dört put: 10, 20, 30, 40. Her put konumu 1 ilerletir: pos 4.
flip(): sınır = eski konum (4), konum = 0. Okunabilir veri 0–3.
İki get: 10 ve 20. Okunmamış 30 ve 40 kaldı.
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.
50 ve 60 konum 2 ve 3'e yazılır.
Yeniden okuma moduna: lim 4, pos 0. Okunacak: 30, 40, 50, 60.
remaining() = lim − pos = 4.
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));