Java'da dosya içinde kelime arama, dosyayı satır satır okuyup her satırı aradığın kelimeyle karşılaştırarak yapılır. Dosyayı okumak tek başına yeterli değildir, çünkü okunan satırın aradığın kelimeyi içerip içermediğine ancak bir arama koşuluyla karar verirsin. Bu yazıda yolu doğrulamayı, okuma yöntemini seçmeyi ve eşleşen satırları numarasıyla yazdırmayı adım adım kuracaksın.
Dosyada kelime aramanın mantığı: okumak yetmez, karşılaştırmak gerekir
Dosya okumayı biliyorsan elinde zaten satırlar var. Aramayı kuran şey, bu satırlara ne sorduğundur. Akışı kodu yazmadan önce dört adımda düşünebilirsin:
- Dosya yolunu doğrula: dosya var mı, gerçekten bir dosya mı?
- Satırları baştan sona sırayla oku ve her turda satır numarasını bir artır.
- Her satırı arama koşuluyla karşılaştır: satır, aranan ifadeyi içeriyor mu?
- Koşul doğruysa satır numarasıyla birlikte yazdır ve eşleşme sayacını bir artır.
Bu liste sözde kod gibidir ve dört adımın arkasında üç soru durur. Hangi koşulu kullanacaksın: kelime mi, ifade mi, büyük küçük harf fark eder mi? Hangi veriyi tutacaksın: yalnız sayaç mı, yoksa satır numarası ve satır metni de mi? Ne zaman duracaksın: dosyanın sonunda mı, yoksa ilk eşleşmede mi? Bu soruları önceden yanıtlamak, kodu yazarken yapılan hataları (sayacı yanlış yerde artırmak, numarayı sıfırdan başlatmak gibi) azaltmana yardım edebilir.
Bu tür adım adım kurgu, programlama dilinden bağımsız bir beceridir. Kendi algoritmik düşünmeni ölçmek istersen ücretsiz Algoritmik Düşünme Testine göz atabilirsin.
Path ve Files ile dosya yolunu kontrol et, BufferedReader mı Files.lines mı seç

Dosya yolunu Path.of("notlar.txt") ile ya da daha eski kodlarda sık görülen Paths.get("notlar.txt") ile oluşturursun. Göreli bir yol verirsen program çalıştığı klasöre göre aranır. Okumaya geçmeden önce Files.exists ve Files.isRegularFile ile iki ayrı durumu yakalayabilirsin: dosya hiç yok ya da yol bir klasöre çıkıyor.
Path yol = Path.of("notlar.txt");
if (!Files.exists(yol)) {
System.out.println("notlar.txt bulunamadı.");
return;
}
if (!Files.isRegularFile(yol)) {
System.out.println("Bu yol bir dosya değil, klasör olabilir.");
return;
}
System.out.println("Dosya hazır: " + yol.toAbsolutePath());
Bu parça bir main metodunun içinde çalışır. Dosya varsa çıktı Dosya hazır: ile başlayıp dosyanın tam yolunu gösterir; yoksa ilk mesajı görürsün.
Okuma için iki yaklaşım var. Files.newBufferedReader ile aldığın BufferedReader'da while döngüsüyle readLine() çağırırsın; metot dosya bitince null döndürür. Döngü senin elindedir: satır numarası için bir sayaç tutmak, ilk eşleşmede break ile çıkmak ya da her adımda ara kontrol yapmak kolaydır. Files.lines ise Stream<String> döndürür; filter ve count gibi akış işlemleriyle kısa bir ifade yazarsın. Oracle'ın Files dokümantasyonuna göre bu akış tembel (lazy) doldurulur, yani satırlar işlendikçe okunur ve akışın try-with-resources ile kapatılması gerekir. Akışta satır numarası doğal olarak gelmez; bunu ayrıca üretmek gerekir.
İki yöntemde de karakter kümesi belirtmezsen dokümantasyona göre varsayılan UTF-8'dir. Bu yazıdaki örnekte eşleşen satırın numarasını da yazdıracağımız için BufferedReader ve while döngüsünü seçeceğiz. Yalnızca eşleşen satır sayısı gerekseydi Files.lines ile tek ifade yetebilirdi.
try-with-resources ve IOException ile hatalı durumu okura anlat
Dosya okurken program iki şeyi garanti etmelidir: açtığı kaynağı her durumda kapatmalı, bir şey ters gittiğinde de kullanıcıya anlaşılır bir mesaj vermelidir. try-with-resources birincisini sağlar. Parantez içinde açılan BufferedReader, blok normal bittiğinde de, ortada bir istisna fırlatıldığında da otomatik kapanır. Elle close() yazmak ve onu finally içine koymak zorunda kalmazsın.
Dosya işlemlerinde karşına çıkan IOException bir checked exception'dır: ya catch ile yakalamak ya da metot imzasına throws yazmak zorundasın, yoksa kod derlenmez. Kullanıcıya konuşan bir program yazıyorsan yakalamak daha doğrudur. NoSuchFileException, java.nio.file paketinde yer alır ve IOException'ın alt sınıfıdır. Bu yüzden onu genel IOException'dan önce yakalamalısın; sıra ters olursa derleyici ikinci blokta hata verir.
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
public class DosyaOku {
public static void main(String[] args) {
Path yol = Path.of("notlar.txt");
try (BufferedReader okuyucu =
Files.newBufferedReader(yol, StandardCharsets.UTF_8)) {
int sayac = 0;
while (okuyucu.readLine() != null) {
sayac++;
}
System.out.println(sayac + " satır okundu.");
} catch (NoSuchFileException e) {
System.out.println("notlar.txt bulunamadı, dosya yolunu kontrol et.");
} catch (IOException e) {
System.out.println("Dosya okunurken bir hata oluştu: " + e.getMessage());
}
}
}
Dosya çalışma klasöründe yoksa beklenen çıktı şudur:
notlar.txt bulunamadı, dosya yolunu kontrol et.
Genel IOException bloğu ise izin sorunu gibi diğer okuma hatalarını yakalar. Files.newBufferedReader ile okurken dosyanın baytları seçtiğin karakter kodlamasına uymazsa MalformedInputException fırlatılabilir. Bu da IOException'ın alt sınıfıdır, yani aynı genel blok onu da yakalar. Kodlama konusuna bir sonraki bölümde döneceğiz.
Kelime mi cümle mi? Harf duyarlılığı, Locale ve UTF-8 kararları

Tek kelime aramak ile birden fazla kelimeli bir ifade aramak aynı yöntemle yapılır: String.contains. Aranan metin "algoritma" da olabilir, "veri yapıları" da; metot yalnızca bu karakter dizisinin satırın içinde ardışık olarak geçip geçmediğine bakar. Varsayılan olarak karşılaştırma harf duyarlıdır, yani Algoritma ile algoritma farklı sayılır. Duyarsız arama için hem satırı hem aranan ifadeyi aynı biçimde küçük harfe çevirip karşılaştırırsın.
Türkçe metinlerde asıl dikkat noktası burada başlar. Parametresiz toLowerCase() sistemin yerel ayarına göre çalışır; programı farklı bilgisayarlarda çalıştırınca sonuç değişebilir. Büyük İ harfi Locale.ROOT ile küçültüldüğünde tek bir i değil, i ve birleşik nokta karakterinden oluşan iki karakterlik bir dizi üretir; böyle bir satırda algoritma araması başarısız olur. Büyük I ise Türkçe yerel ayarla ı olur. Çözüm, yerel ayarı açıkça vermektir:
Locale tr = Locale.forLanguageTag("tr-TR");
String satir = "ALGORİTMA ve veri yapıları";
String aranan = "algoritma";
boolean kelime = satir.toLowerCase(tr).contains(aranan.toLowerCase(tr));
boolean ifade = satir.toLowerCase(tr).contains("veri yapıları");
System.out.println(kelime);
System.out.println(ifade);
Beklenen çıktı:
true
true
Aynı satırı Locale.ROOT ile küçültürsen İ yüzünden ilk karşılaştırma eşleşmeyebilir. Ters yönde de dikkat et: dosyada noktasız ALGORITMA yazıyorsa Türkçe yerel ayar onu algorıtma yapar. Verinin nasıl yazıldığını bilmek ve karşılaştırmayı buna göre seçmek gerekir.
Kodlama için de aynı açıklık geçerlidir. Okuyucuyu StandardCharsets.UTF_8 ile açarsan dosyanın UTF-8 olduğunu varsaydığını koda yazmış olursun. Dosya başka bir kodlamada kaydedildiyse ş, ğ, ı gibi harfler bozulur ya da okuma sırasında hata alırsın. Dosyayı metin düzenleyicinde UTF-8 olarak kaydetmek bu sorunu baştan önler. String metotları, istisnalar ve dosya işlemleri konusunda nerede durduğunu görmek istersen ücretsiz Java bilgi testi ile seviyeni ölçebilirsin.
Çalışan Örnek: notlar.txt İçinde 'algoritma' Geçen Satırlar ve Eşleşme Sayısı
Önce arayacağımız dosyayı hazırlayalım. Proje klasörüne UTF-8 olarak kaydedilmiş notlar.txt adında, şu 5 satırlık bir dosya koy:
Bugün algoritma konusuna başladık.
Döngüler ve koşullar tekrar edildi.
ALGORİTMA akış şemasıyla çizilir.
Ödev: iki algoritma sorusu çöz.
Yarın dizilere geçeceğiz.
Aşağıdaki sınıf dosyayı satır satır okur, her satırı aranan ifadeyle karşılaştırır ve eşleşenleri numarasıyla yazdırır:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Locale;
public class KelimeArama {
public static void main(String[] args) {
Path yol = Path.of("notlar.txt");
String aranan = "algoritma";
Locale tr = Locale.forLanguageTag("tr-TR");
String arananKucuk = aranan.toLowerCase(tr);
if (!Files.exists(yol)) {
System.out.println("Dosya bulunamadı: " + yol.toAbsolutePath());
return;
}
int satirNo = 0;
int eslesenSatir = 0;
try (BufferedReader okuyucu = Files.newBufferedReader(yol, StandardCharsets.UTF_8)) {
String satir;
while ((satir = okuyucu.readLine()) != null) {
satirNo++;
if (satir.toLowerCase(tr).contains(arananKucuk)) {
System.out.println("Satır " + satirNo + ": " + satir);
eslesenSatir++;
}
}
System.out.println("Toplam eşleşen satır: " + eslesenSatir);
} catch (NoSuchFileException e) {
System.out.println("Dosya okunurken bulunamadı: " + e.getFile());
} catch (IOException e) {
System.out.println("Dosya okunurken hata oluştu: " + e.getMessage());
}
}
}
Beklenen çıktı:
Satır 1: Bugün algoritma konusuna başladık.
Satır 3: ALGORİTMA akış şemasıyla çizilir.
Satır 4: Ödev: iki algoritma sorusu çöz.
Toplam eşleşen satır: 3
Bu kodda verilen dört karar
1. Arama ölçütü bir değişkende. aranan değişkeni sayesinde başka bir kelimeyi aramak için yalnızca tek satırı değiştirirsin. Aynı değişkeni sonradan args ya da Scanner ile kullanıcıdan gelen değere de bağlayabilirsin.
2. Küçük harfe çevirip karşılaştırma. Satır 3'te kelime büyük harfle, ALGORİTMA olarak yazılmış ve yine yakalanıyor. Hem satır hem aranan ifade aynı kuralla küçültüldüğü için büyük küçük harf farkı ortadan kalkar. Locale.forLanguageTag("tr-TR") seçimi, Türkçedeki noktalı İ ve noktasız ı harflerinin doğru dönüşmesi içindir. Yerel ayarı belirtmezsen sonuç, programın çalıştığı bilgisayarın dil ayarına göre değişebilir.
3. Satır numarası elle sayılıyor. BufferedReader ile readLine() çağrısı yalnızca metni verir, numarayı vermez. Bu yüzden döngünün başında satirNo++ yapıyoruz. Numara, okunan satırla aynı adımda arttığı için her zaman doğru kalır.
4. Sayaç satır başına bir artıyor. eslesenSatir yalnızca contains doğru döndüğünde bir artar. Bir satırda kelime iki kez geçse de o satır tek sayılır. Kelimenin kaç kez tekrarlandığını saymak istersen satırın içinde indexOf ile ilerleyen ayrı bir iç döngü gerekir. Bu, "kaç satırda geçiyor" sorusundan farklı bir sorudur.
Örneği Geliştirmek İçin Kontrol Listesi ve Sonraki Adımlar
Aşağıdaki adımları sırayla, her birini ayrı küçük bir deneme olarak ekleyebilirsin:
- Aranan ifadeyi koda yazmak yerine
mainmetodununargsparametresinden ya daScannerile klavyeden al. - Tek dosya yerine birden fazla dosya adını bir listeye koyup aynı arama mantığını her biri için çalıştır.
- Eşleşen kısmı vurgula:
indexOfile konumu bulup satırı üçe bölebilir, kelimenin çevresine işaret koyabilirsin. - Tam kelime eşleşmesi için eşleşmenin başındaki ve sonundaki karakterin harf olup olmadığını denetle (ayrıntısı aşağıdaki sorularda).
- Sonuçları ekrana yazdırmak yerine
Files.newBufferedWriterile ayrı bir dosyaya yazdır.
Dosya işlemleri, istisnalar ve koleksiyonları birbirine bağlayan bu tür küçük projeleri düzenli ve takipli ilerletmek istersen, Lise ve Üniversite öğrencilerine yönelik kişiye özel müfredat ve ödev takibiyle ilerleyen birebir Java özel ders programına göz atabilirsin.
Sık Sorulan Sorular
Kelimenin tam eşleşmesi nasıl aranır?
contains "algoritmalar" ya da "algoritmik" gibi sözcüklerin içindeki parçayı da yakalar. Tam kelime için aranan ifadenin öncesinde ve sonrasında harf ya da rakam olmaması gerekir. Bunu düzenli ifadeyle kurabilirsin: Pattern.compile("(?<![\p{L}\p{N}])" + Pattern.quote(arananKucuk) + "(?![\p{L}\p{N}])"). Deseni küçültülmüş satıra uygula: desen.matcher(satir.toLowerCase(tr)).find(). p{L} Türkçe harfleri de kapsar.
Aranan kelime bir satırda birden fazla geçiyorsa nasıl sayılır?
Satırı küçülttükten sonra indexOf ile ilk konumu bul, sonra aramaya bulunan konumun hemen sonrasından devam et. Her bulduğunda bir sayaç artır:
String s = "algoritma ve algoritma".toLowerCase(Locale.forLanguageTag("tr-TR"));
String k = "algoritma";
int sayi = 0;
int konum = s.indexOf(k);
while (konum != -1) {
sayi++;
konum = s.indexOf(k, konum + k.length());
}
System.out.println(sayi);
Bu parça 2 yazdırır. Toplamı tüm dosya için tutmak istersen bu sayaç döngünün dışında tanımlanmalıdır.
Java'da dosya bulunamadı hatası alıyorum, nereye bakmalıyım?
Path.of("notlar.txt") göreli bir yoldur ve programın çalıştığı klasöre göre aranır. Çoğu geliştirme ortamında bu klasör proje köküdür, dosyanın bulunduğu klasör olmayabilir. yol.toAbsolutePath() değerini yazdırarak Java'nın dosyayı tam olarak nerede aradığını görebilirsin. Ayrıca dosya adını ve uzantısını kontrol et; Windows'ta gizli uzantılar yüzünden dosya aslında notlar.txt.txt olabilir.
Türkçe karakterler dosyadan bozuk geliyorsa ne yapmalıyım?
Dosyanın hangi kodlamayla kaydedildiğine bak. Metin düzenleyicinde dosyayı UTF-8 olarak kaydet ve okurken StandardCharsets.UTF_8 belirt. Dosya başka bir kodlamayla kaydedilmişse Files.newBufferedReader bazen MalformedInputException fırlatır; bu da IOException türündedir ve örnekteki ikinci catch bloğuna düşer.
Dosyayı okumak işin yalnızca yarısıdır; her satırı bir ölçütle karşılaştırıp sonucu saymak aramayı oluşturur. notlar.txt örneğindeki yapıyı kendi dosyalarında ve kendi aradığın ifadelerle denedikçe okuma, karşılaştırma ve sayma adımlarını birbirinden ayırmak kolaylaşacaktır.