Search for a Word in a File in Java
Problem
Searching a file line by line keeps memory use small, and line numbers make each match easy to find in the original file.
Find every line in a server log that contains the word ERROR, printing its line number and text.
Java Program
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SearchWordInFile {
public static void main(String[] args) throws IOException {
Path file = Paths.get("server.log");
Files.writeString(file,
"10:00 INFO started\n10:02 WARN slow disk\n10:05 ERROR timeout\n10:07 INFO ok\n10:09 ERROR retry failed\n");
String word = "ERROR";
int lineNo = 0, matches = 0;
try (BufferedReader reader = Files.newBufferedReader(file)) {
String line;
while ((line = reader.readLine()) != null) {
lineNo++;
if (line.contains(word)) { // case-sensitive substring match
matches++;
System.out.println("Line " + lineNo + ": " + line);
}
}
}
System.out.println(matches + " lines contain \"" + word + "\"");
Files.delete(file);
}
}Output
Core Logic
Reading one line at a time, a counter tracks the line number and contains tests each line for the word.
- 1The program writes a sample
server.logfirst. - 2A
BufferedReaderreads it in awhileloop, incrementinglineNo. - 3
line.contains(word)checks each line; matches are counted and printed. - 4A summary line reports the total.
Key Point: contains is case-sensitive and matches inside longer words — "ERRORS" would also match.
Why: Every character is read once, and only one line is held at a time.
Key Concepts
Approach 2: Whole-Word, Case-Insensitive Search
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SearchWordInFileRegex {
public static void main(String[] args) throws IOException {
Path file = Paths.get("notes.txt");
Files.writeString(file, "Java is fun.\nJavaScript is different.\nI drink java every morning.\n");
Pattern whole = Pattern.compile("\\bjava\\b", Pattern.CASE_INSENSITIVE); // whole word, any case
int count = 0;
for (String line : Files.readAllLines(file)) {
Matcher m = whole.matcher(line);
while (m.find()) count++;
}
System.out.println("Whole-word matches for \"java\": " + count);
Files.delete(file);
}
}
Output
Core Logic
A regular expression with word boundaries finds whole words only, in any letter case.
- 1
\\bjava\\bmatches "java" only where it isn't part of a longer word. - 2
CASE_INSENSITIVEalso matches "Java". - 3
while (m.find())counts every match on each line, not just the first.
Key Point: Compile the Pattern once outside the loop; compiling a regex for every line is wasted work.
Why: readAllLines holds the file in memory, then each character is scanned once.
Key Concepts
Interview Questions
How would you search a very large file quickly?
Stream it line by line with Files.lines and filter, which keeps memory low; for repeated searches, build an index instead of rescanning.
How do you search every file in a folder?
Walk the folder with Files.walk, filter regular files (and maybe by extension), and run the same line search on each.