20

I'm currently trying to read lines from a text only file that I have. I found on another stackoverflow(Reading a plain text file in Java) that you can use Files.lines(..).forEach(..) However I can't actually figure out how to use the for each function to read line by line text, Anyone know where to look for that or how to do so?

Community
  • 1
  • 1
user3570058
  • 201
  • 1
  • 2
  • 3
  • That method is already reading each line of the file, you can store the line in a `String` variable and do something else with it... – Luiggi Mendoza Apr 24 '14 at 17:59
  • Uhm, you should read about Java 8 and lambdas; specifically here, about `Consumer` and the notion of single abstract method – fge Apr 24 '14 at 18:00

5 Answers5

34

Sample content of test.txt

Hello
Stack
Over
Flow
com

Code to read from this text file using lines() and forEach() methods.

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 FileLambda {

    public static void main(String JavaLatte[]) {
        Path path = Paths.get("/root/test.txt");
        try (Stream<String> lines = Files.lines(path)) {
            lines.forEach(s -> System.out.println(s));
        } catch (IOException ex) {
          // do something or re-throw...
        }
    }
}
Kwadz
  • 1,755
  • 1
  • 17
  • 33
pardeep131085
  • 5,280
  • 2
  • 18
  • 9
  • 3
    You may use method reference: `System.out::println`, still it would be translated to the same bytecode. – Dmitry Ginzburg Dec 15 '14 at 08:58
  • 1
    And one more point: you should not store `Stream` as variable because it may confuse some readers to use it twice or more times, which is prohibited. Instead, you may save it to `List` with `readAllLines`, then use method `stream()` on this list. – Dmitry Ginzburg Dec 15 '14 at 08:59
  • 9
    Use try-with-resources for the stream to ensure it gets auto-closed: `try (Stream lines = Files.lines(path)) {` – oldo Feb 28 '15 at 23:29
  • @DmitryGinzburg Would you store the `Stream` as a variable for files too big for `readAllLines`? – Noumenon Aug 18 '15 at 16:06
  • @Noumenon why should I? I can use `Files.lines` result immediately. – Dmitry Ginzburg Aug 18 '15 at 16:54
  • @DmitryGinzburg I got this confused with a try-with-resources answer on a different page. Sorry for bothering you. – Noumenon Aug 18 '15 at 17:28
  • 2
    Please don't ever write empty catch blocks like this in production code. – Natix Dec 15 '16 at 10:05
7

Avoid returning a list with:

List<String> lines = Files.readAllLines(path); //WARN

Be aware that the entire file is read when Files::readAllLines is called, with the resulting String array storing all of the contents of the file in memory at once. Therefore, if the file is significantly large, you may encounter an OutOfMemoryError trying to load all of it into memory.

Use stream instead: Use Files.lines(Path) method that returns a Stream<String> object and does not suffer from this same issue. The contents of the file are read and processed lazily, which means that only a small portion of the file is stored in memory at any given time.

Files.lines(path).forEach(System.out::println);
orirab
  • 1,790
  • 17
  • 28
Imar
  • 301
  • 4
  • 7
  • I have a doubt here. Will the Files.lines() return stream of each line or will it return a stream out of the whole file? Please clarify. – Ashish Singh Aug 01 '20 at 09:23
6

With Java 8, if file exists in a classpath:

Files.lines(Paths.get(ClassLoader.getSystemResource("input.txt")
                    .toURI())).forEach(System.out::println);
Arpit Aggarwal
  • 21,748
  • 13
  • 80
  • 99
3

Files.lines(Path) expects a Path argument and returns a Stream<String>. Stream#forEach(Consumer) expects a Consumer argument. So invoke the method, passing it a Consumer. That object will have to be implemented to do what you want for each line.

This is Java 8, so you can use lambda expressions or method references to provide a Consumer argument.

Sotirios Delimanolis
  • 252,278
  • 54
  • 635
  • 683
2

I have created a sample , you can use the Stream to filter/

public class ReadFileLines {
    public static void main(String[] args) throws IOException {
        Stream<String> lines = Files.lines(Paths.get("C:/SelfStudy/Input.txt"));
//      System.out.println(lines.filter(str -> str.contains("SELECT")).count());

//Stream gets closed once you have run the count method.
        System.out.println(lines.parallel().filter(str -> str.contains("Delete")).count());
    }
}

Sample input.txt.

SELECT Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Kumar Abhishek
  • 2,448
  • 25
  • 26