Is is possible to list file characteristics from .forEach method?

Viewed 192

I'm trying to use more Java 8 syntax. I have a simple use case here, listing files recursively, where I'd like to print more than just the file name as the example shows:

public void listFiles(String path) {
    try {
        Files.walk(Paths.get(path))
             .filter(p -> {
                 return Files.isRegularFile(p);
             })
              .forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Is there a way to call a method from the forEach method, passing the file in question as a parameter? How would I reference the file?

Edit: There was some confusion in the discussion about whether the path of each file being printed could be passed as a variable to another method.

To confirm, it can. Here's the code:

 public void listFiles(String path) {
        try {
            Files.walk(Paths.get(path))
                    .filter(p -> {
                        return Files.isRegularFile(p);
                    })
                    .forEach(p -> myMethod(p));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void myMethod(Path path) {
        System.out.println(path.toAbsolutePath());
        try {
            BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
            FileTime fileTime = attr.lastModifiedTime();
            System.out.println("file date: " + fileTime);
        } catch (IOException ex) {
            // handle exception
        }
    }
1 Answers

You can either use the method map as long as you care only about one parameter passed down the pipeline.

Files.walk(Paths.get(path))
     .filter(p -> Files.isRegularFile(p))
     .map(Path::getFileName)
     .forEach(System.out::println);

Or you can expand the method parameter into a lambda expression within the forEach method consuming the whole Path that passed through the filter (is a regular file):

Files.walk(Paths.get(path))
     .filter(p -> Files.isRegularFile(p))
     .forEach(p -> System.out.println("Path fileName: " + p.getFileName()));

To avoid confusion, the variable p is accessible only within the scope of the filter/forEach method parameter, ie. lambda expression. See the last snippet expanded:

Files.walk(Paths.get(""))
     .filter(path1 -> Files.isRegularFile(path1))
     .forEach(new Consumer<Path>() {
         @Override
         public void accept(final Path p) {          
             // here is the `p`. It lives only in the scope of this method                 
             System.out.println("Path fileName: " + p.getFileName());
         }});
Related