In this Java tutorial, you will learn how to read contents of a File line by line using Stream in Java 8, with examples using Files.lines(), try-with-resources, charset handling, filtering, and collecting lines.
Read file line by line using Stream in Java 8
To read a file line by line using Stream in Java 8, use Files.lines(Path) or Files.lines(Path, Charset). The method returns a Stream<String>, where each element in the stream represents one line from the file.
This approach is useful when you want to process a text file using Java Stream operations such as forEach(), filter(), map(), limit(), or collect(). Since the stream is backed by an open file resource, close it after use. The simplest safe way is to use try-with-resources.
Java 8 Files.lines() syntax for reading a text file as Stream
The steps to read contents of a File line by line using Stream in Java are
Step 1: Use Files.lines to get Stream<String>
Stream<String> stream = Files.lines(Path path, Charset cs)
Stream<T> contains elements of type T. Stream<String> contains strings which are lines from the contents of file(specified by the Path).
You can also use the shorter method when the file is encoded in UTF-8.
Stream<String> stream = Files.lines(path);
If the file uses another encoding, pass the required Charset explicitly.
Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8);
Step 2: Use Stream.forEach(action) to do the specified action on each String of the Stream<String> object.
stream.forEach(System.out::println);
We chose the action to “Print the String element (here line) to the output console”.
For normal application code, wrap Files.lines() inside try-with-resources so that the file is closed automatically.
try (Stream<String> stream = Files.lines(path)) {
stream.forEach(System.out::println);
}
Java 8 Stream examples to read file line by line
1. Read File Line by Line – Java 8 Stream
In this example, we have a text file named samplefile.txt, and we will read contents of this file, line by line, using Stream class.
samplefile.txt
This is first line.
This is second line.
This is third line.
Welcome to www.tutorialkart.com.
Example.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* Read contents of a File line by line using Stream in Java 8
* www.tutorialkart.com
*/
public class Example {
public static void main(String[] args) {
String filename = "samplefile.txt";
Path path = Paths.get(filename);
Stream<String> stream;
try {
// read the contents of the file to a Stream
stream = Files.lines(path);
// System.out::println is the action to be done on each element, i.e., line in the file
stream.forEach(System.out::println);
} catch (IOException e) {
System.out.println("There is an exception because of the file. Please check.");
e.printStackTrace();
}
}
}
When the above program is run, output to the console is as shown in the following.
Output
This is first line.
This is second line.
This is third line.
Welcome to www.tutorialkart.com.
Note: Provide the path to the file correctly. In this example, the file is placed at the root of Project Folder (of Eclipse Project).
The above example explains the basic idea. In the next example, we use try-with-resources, which is the recommended style because it closes the stream automatically after the file has been processed.
2. Read file line by line using Files.lines() with try-with-resources
Files.lines() opens a file resource. If you do not close the stream, the file handle may remain open until the stream is closed by other means. The following Java 8 example uses try-with-resources to close the stream safely.
Example.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
Path path = Paths.get("samplefile.txt");
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(System.out::println);
} catch (IOException e) {
System.out.println("Unable to read the file: " + path);
e.printStackTrace();
}
}
}
Use this form when you only need to read and process the lines inside the same block. Do not return the stream from a method after the try-with-resources block, because the stream will already be closed.
3. Read file line by line using Stream and UTF-8 charset
If your file contains non-ASCII text, make the charset explicit. This avoids confusion when the file is created by another program or on another operating system.
Example.java
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
Path path = Paths.get("samplefile.txt");
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
lines.forEach(System.out::println);
} catch (IOException e) {
System.out.println("Unable to read the file using UTF-8 charset.");
e.printStackTrace();
}
}
}
Use another charset only when you know that the file was saved in that encoding. For example, some old text files may use ISO_8859_1 instead of UTF-8.
4. Filter lines while reading a file using Java Stream
One advantage of reading a file with Stream is that you can process each line using Stream operations. In the following example, blank lines are skipped before printing.
Example.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
Path path = Paths.get("samplefile.txt");
try (Stream<String> lines = Files.lines(path)) {
lines.filter(line -> !line.trim().isEmpty())
.forEach(System.out::println);
} catch (IOException e) {
System.out.println("Unable to read the file.");
e.printStackTrace();
}
}
}
You can replace the filter condition with any condition required by your program. For example, you may print only lines that contain a keyword.
lines.filter(line -> line.contains("tutorial"))
.forEach(System.out::println);
5. Collect file lines into a List using Java 8 Stream
If you need all lines after reading the file, collect the stream into a List<String>. Use this approach only when the file size is reasonable for memory.
Example.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
Path path = Paths.get("samplefile.txt");
try (Stream<String> lines = Files.lines(path)) {
List<String> lineList = lines.collect(Collectors.toList());
System.out.println("Number of lines: " + lineList.size());
} catch (IOException e) {
System.out.println("Unable to read the file.");
e.printStackTrace();
}
}
}
For large files, prefer processing each line directly in the stream pipeline instead of collecting all lines into memory.
Files.lines() vs Files.readAllLines() in Java 8
Both Files.lines() and Files.readAllLines() can read text files, but they are used differently.
| Java file reading method | Return type | Best used when |
|---|---|---|
Files.lines(path) | Stream<String> | You want to process lines using Stream operations and avoid loading every line at once. |
Files.readAllLines(path) | List<String> | You need all lines in memory and the file is small enough to load safely. |
For line-by-line processing in Java 8, Files.lines() is usually the better fit. For small files where you need random access to the list of lines, Files.readAllLines() can be simpler.
Common errors while reading a file line by line using Stream
- Wrong file path: If the file is not in the expected folder,
Files.lines()throws anIOException. Use an absolute path or confirm the current working directory. - Stream already closed: A stream can be consumed only once. Do not try to reuse the same stream after
forEach(),collect(), or another terminal operation. - File handle not closed: Use try-with-resources so the stream and the underlying file resource are closed correctly.
- Incorrect charset: If text appears incorrectly, read the file with the charset that was used to create it.
- Collecting a very large file: Avoid collecting all lines into a list when the file is too large for available memory.
QA checklist for Java 8 Stream file-reading examples
- Confirm that
samplefile.txtexists in the project root or provide the correct absolute file path. - Use try-with-resources for every new
Files.lines()example so the stream is closed. - Use
StandardCharsets.UTF_8when the file encoding must be explicit. - Do not reuse a
Stream<String>after a terminal operation such asforEach()orcollect(). - Use
Files.lines()for stream processing andFiles.readAllLines()only when loading all lines into memory is acceptable.
FAQs on reading file line by line using Stream in Java 8
How to read file line by line using Stream in Java 8?
Use Files.lines(path) to get a Stream<String>, then process each line with a Stream terminal operation such as forEach(). Wrap it in try-with-resources so that the file resource is closed automatically.
Why should Files.lines() be used with try-with-resources?
Files.lines() opens a file-backed stream. try-with-resources closes the stream automatically after the block finishes, which also releases the underlying file resource.
Can I filter file lines while reading with Java Stream?
Yes. You can use Stream operations such as filter(), map(), and limit() before a terminal operation. For example, lines.filter(line -> !line.trim().isEmpty()) skips blank lines.
What is the difference between Files.lines() and readAllLines()?
Files.lines() returns a stream for line-by-line processing, while Files.readAllLines() reads all lines into a list. Use Files.lines() for stream processing or larger files, and readAllLines() for small files when you need all lines in memory.
Can a Java Stream from Files.lines() be reused?
No. A Java Stream can be consumed only once. After a terminal operation such as forEach() or collect(), create a new stream if you need to read the file again.
Conclusion
In this tutorial we have seen how to use java.util.stream.Stream to read the contents of a file line by line. For Java 8 programs, Files.lines() with try-with-resources is the safest common pattern. Use Stream operations when you want to filter, transform, print, or collect file lines while reading the file.
TutorialKart.com