Tenth Line
EasyPrompt
Given a text file file.txt, print just the 10th line of the file.
Example:
Assume that file.txt has the following content:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10Your script should output the tenth line, which is:
Line 101. If the file contains less than 10 lines, what should you output?
2. There's at least three different solutions. Try to explore all possibilities.
Approaches
3 approaches with complexity analysis and trade-offs.
A more memory-efficient approach is to read the file line by line, keeping track of the current line number. We stop reading and print the line as soon as we reach the 10th line.
Algorithm
- Initialize a line counter to 0.
- Open
file.txtusing aBufferedReader. - Read the file line by line in a loop.
- For each line, increment the counter.
- If the counter reaches 10, print the current line and exit the loop.
- If the end of the file is reached before the counter hits 10, do nothing.
Walkthrough
This method avoids loading the entire file into memory. Instead, it processes the file as a stream. We use a BufferedReader to read the file one line at a time. A counter variable is initialized to 1 and incremented for each line read. When the counter equals 10, we've found our target line. We print it and can immediately stop processing the rest of the file by breaking the loop. If the loop finishes (i.e., we reach the end of the file) and the counter is less than 10, it means the file has fewer than 10 lines, and nothing is printed.
import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException; public class IterativeRead { public static void main(String[] args) { String fileName = "file.txt"; try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { String line; int lineCount = 0; while ((line = reader.readLine()) != null) { lineCount++; if (lineCount == 10) { System.out.println(line); break; // Stop reading after the 10th line } } } catch (IOException e) { System.err.println("Error reading file: " + e.getMessage()); } }}Complexity
Time
O(L), where L is the number of characters up to the 10th line. In the worst case (file has fewer than 10 lines), it's O(N), where N is the total number of characters. For any file with at least 10 lines, this is constant time relative to the file size.
Space
O(M), where M is the maximum length of a line in the file. This is because we only need to store one line at a time. It's often considered O(1) or constant space.
Trade-offs
Pros
Very memory efficient; suitable for files of any size.
Time efficient, as it stops reading as soon as the target line is found.
Cons
Slightly more verbose than the first approach.
Does not provide random access to other lines without re-reading the file.
This approach involves reading all lines from the file and storing them in a list in memory. Once the entire file is read, we can easily access the 10th line by its index if it exists.
Algorithm
- Read all lines from
file.txtinto aList<String>. - Check if the size of the list is 10 or more.
- If it is, print the string at index 9 of the list.
- If the file has fewer than 10 lines, or an error occurs, nothing is printed.
Walkthrough
The simplest, but most memory-intensive, way to solve this is to read the whole file into a data structure, like an ArrayList. We can use Java's Files.readAllLines() method, which conveniently reads all lines from a file into a List<String>. After loading all lines, we check if the list contains at least 10 lines. If it does, we retrieve and print the element at index 9 (since lists are 0-indexed). If the file has fewer than 10 lines, the list size will be less than 10, and we do nothing, effectively handling the edge case.
import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import java.util.List; public class ReadAllLines { public static void main(String[] args) { String fileName = "file.txt"; try { List<String> allLines = Files.readAllLines(Paths.get(fileName)); if (allLines.size() >= 10) { System.out.println(allLines.get(9)); } } catch (IOException e) { System.err.println("Error reading file: " + e.getMessage()); } }}Complexity
Time
O(N), where N is the total number of characters in the file. The entire file must be read and parsed.
Space
O(N), where N is the total number of characters in the file. All lines are stored in memory.
Trade-offs
Pros
Very simple to write and understand using modern Java APIs.
Provides random access to any line after the initial read.
Cons
Highly inefficient for large files, as it can consume a large amount of memory and potentially cause an
OutOfMemoryError.Unnecessary work is done by reading the entire file when only the 10th line is needed.
For environments where shell tools are available (like Linux or macOS), the most idiomatic and often fastest solution is to delegate the task to specialized command-line utilities like sed, awk, or a combination of head and tail.
Algorithm
- Construct a shell command string that extracts the 10th line (e.g.,
sed -n '10p' file.txt). - Use Java's
ProcessBuilderorRuntime.getRuntime().exec()to execute the command. - Capture the standard output stream of the created process.
- Read the line from the output stream and print it to the console.
- Handle potential errors during process execution.
Walkthrough
This approach leverages the power and efficiency of standard Unix/Linux tools that are highly optimized for text processing. We can execute these commands from within a Java program.
sed(Stream Editor): The commandsed -n '10p' file.txtis perfect for this.-nsuppresses default output, and10pprints only the 10th line.awk: The commandawk 'NR == 10' file.txtworks similarly.NRis the record (line) number, and the default action for a true condition is to print the line.headandtail: The pipelinehead -n 10 file.txt | tail -n 1first takes the top 10 lines, thentailtakes the last line from that output, which is the 10th line.
We can execute these from Java using the ProcessBuilder class, which allows us to run external commands and read their output.
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException; public class ShellCommand { public static void main(String[] args) { // This assumes a Unix-like environment with 'sed' available. String[] command = {"/bin/sh", "-c", "sed -n '10p' file.txt"}; try { ProcessBuilder pb = new ProcessBuilder(command); Process process = pb.start(); // Read the output from the command try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; if ((line = reader.readLine()) != null) { System.out.println(line); } } process.waitFor(); // Wait for the process to finish } catch (IOException | InterruptedException e) { System.err.println("Error executing command: " + e.getMessage()); } }}Complexity
Time
O(L), where L is the number of characters up to the 10th line. The underlying native tools are highly optimized and stop processing early.
Space
O(1). The external process handles the file stream with minimal memory usage. The Java wrapper itself uses negligible memory.
Trade-offs
Pros
Extremely concise and leverages highly optimized, battle-tested system tools.
Often the fastest practical solution.
Considered the standard 'scripting' solution for this type of problem.
Cons
Not platform-independent. It relies on the presence of specific shell commands (e.g.,
sed), making it unsuitable for pure-Java, cross-platform applications.Adds complexity related to process management and error handling (e.g., command not found, shell errors).
Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.