I want to use this code to read only the first line from a file:
String line = Files.lines(path).findFirst().get();
I assume that this does NOT load the contents of the entire file into memory. Instead, it opens the file, reads ONLY the first line and then closes the file.
Is my assumption correct?
Java supports several file-reading features. One such utility is reading a specific line in a file. We can do this by simply providing the desired line number; the stream will read the text at that location. The Files class can be used to read the n t h nth nth line of a file.
Java 8 has added a new method called lines() in the Files class which can be used to read a file line by line in Java. The beauty of this method is that it reads all lines from a file as Stream of String, which is populated lazily as the stream is consumed.
We can use java. io. BufferedReader readLine() method to read file line by line to String. This method returns null when end of file is reached.
From the Files Javadoc:
static Stream lines(Path path) - Read all lines from a file as a Stream.
Files.lines(path)
reads all lines, meaning they have the potential to be accessed, but what's loaded into memory depends on what's required for the stream. In your case, only the first line will be accessed (stored in memory), since the BufferedReader
is able to lazily load contents into memory as necessary.
The Files#lines
method uses a BufferedReader
class to access the lines using BufferedReader#lines
. From the source
Returns a Stream, the elements of which are lines read from this BufferedReader. The java.util.stream.Stream is lazily populated, i.e., read only occurs during the terminal stream operation. The reader must not be operated on during the execution of the terminal stream operation. Otherwise, the result of the terminal stream operation is undefined.
After execution of the terminal stream operation there are no guarantees that the reader will be at a specific position from which to read the next character or line.
If an IOException is thrown when accessing the underlying BufferedReader, it is wrapped in an UncheckedIOException which will be thrown from the Stream method that caused the read to take place. This method will return a Stream if invoked on a BufferedReader that is closed. Any operation on that stream that requires reading from the BufferedReader after it is closed, will cause an UncheckedIOException to be thrown.
public Stream<String> lines() {
Iterator<String> iter = new Iterator<String>() {
String nextLine = null;
@Override
public boolean hasNext() {
if (nextLine != null) {
return true;
} else {
try {
nextLine = readLine();
return (nextLine != null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
@Override
public String next() {
if (nextLine != null || hasNext()) {
String line = nextLine;
nextLine = null;
return line;
} else {
throw new NoSuchElementException();
}
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
}
The Stream
created by StreamSupport.stream
is backed by an Iterator
. The stream is only asked for one element because you call Stream#findFirst
. Therefore only one call to hasNext
and next
are made, meaning that BufferedReader#readLine
is only called once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With