4

I'm trying to write a method that lists all non-hidden files in a directory. However, when I add the condition !Files.isHidden(filePath) my code won't compile, and the compiler returns the following error:

java.lang.RuntimeException: Uncompilable source code - unreported exception 
java.io.IOException; must be caught or declared to be thrown

I tried to catch the IOException, but the compiler still refuses to compile my code. Is there something glaringly obvious that I'm missing? Code is listed below.

try {    
    Files.walk(Paths.get(root)).forEach(filePath -> {
        if (Files.isRegularFile(filePath) && !Files.isHidden(filePath)) {
            System.out.println(filePath);            
        } });
} catch(IOException ex) {    
  ex.printStackTrace(); 
} catch(Exception ex) {   
  ex.printStackTrace(); 
}
Nivetha T
  • 481
  • 1
  • 3
  • 17

2 Answers2

6

The lambda expression passed to Iterable#forEach isn't allowed to throw an exception, so you need to handle it there:

Files.walk(Paths.get(root)).forEach(filePath -> {
    try {
        if (Files.isRegularFile(filePath) && !Files.isHidden(filePath)) {
            System.out.println(filePath);
        }
    } catch (IOException e) {
        e.printStackTrace(); // Or something more intelligent
    }
});
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    Note that in general lambda expression is *allowed* to throw an exception. It's not allowed in particular functional interface which is used here. – Tagir Valeev Aug 16 '15 at 16:08
  • 1
    @TagirValeev I thought that using "The" instead of "A" in my answer conveyed that notion, but upon re-reading it I agree the point was not made clearly enough. I edited the text to clarify that point. Thanks for your feedback! – Mureinik Aug 17 '15 at 06:37
  • Well probably that's my problem. In my native language there are no articles, so sometimes I just don't notice the additional meaning they add to the sentence. Nevertheless the clarification is good. – Tagir Valeev Aug 17 '15 at 06:40
4

isHiddenFile() throws an IOException, and you're not catching it. Indeed, forEach() takes a Consumer as argument, and Consumer.accept() can't throw any checked exception. So you need to catch the exception inside by the lambda expression passed to forEach():

Files.walk(Paths.get(root)).forEach(filePath -> {
    try {
        if (Files.isRegularFile(filePath) && !Files.isHidden(filePath)) {
            System.out.println(filePath);            
        } 
    }
    catch (IOException e) {
         // do something here
    }
});
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255