0

I have this simple code that processes files in a designated folder.
processLog method throws IOException, when this happens I would like to exit (no need to continue processing rest of the files) but sadly I have to catch the exception locally.

try (Stream<Path> filePathStream = Files.walk(Paths.get(logs))){
            filePathStream.forEach(filePath -> {
                if (Files.isRegularFile(filePath)) {
                    processLog(filePath.toFile());
                }
            });
        } 

Any idea how I can break the loop? Thanks.

Guy
  • 827
  • 3
  • 11
  • 15

4 Answers4

0

If you want to use a Stream specifically, you could do this:

import java.io.IOException;
import java.util.Arrays;

public class Eg {

    public static void main(String[] args) {
        int[] numbers = new int[] {1,2,3,4,5,6,7,8};
        Arrays.stream(numbers).takeWhile(i -> process(i)).forEach(b ->{});
    }

    private static boolean process(int i) {
        try {
            if (i == 6) {
                throw new IOException();
            }
            System.out.println("processed " + i);
            return true;
        } catch (IOException e) {
            System.out.println("failed on " + i);
            return false;
        }
    }
}

The final empty forEach is to force the Stream to be run. You could return a different type if there was something you wanted to do with the results of processing the files.

tgdavies
  • 10,307
  • 4
  • 35
  • 40
0

I think the easiest/cleanest solution is to convert the Stream to an Iterator. Then you can use a "normal" loop which can throw a checked exception. For example:

try (Stream<Path> filePathStream = Files.walk(Paths.get(logs))) {
  // you can filter here instead of in an 'if' block later
  Iterator<Path> itr = filePathStream.filter(Files::isRegularFile).iterator();
  while (itr.hasNext()) {
    processLog(itr.next().toFile());
  }
} catch (IOException ex) {
  // you've now stopped processing
  // do something with 'ex'...
}
Slaw
  • 37,820
  • 8
  • 53
  • 80
-1
try (Stream<Path> filePathStream = Files.walk(Paths.get(logs))){
        filePathStream.forEach(filePath -> {
            if (Files.isRegularFile(filePath))
                processLog(filePath.toFile());
        });
    }catch (IOException e){
        e.printStackTrace();
    }

Add just catch to get the exception, forEach will stop when processLog throw the Exception

  • 1
    Keep in mind that `forEach` takes a `Consumer`, which cannot throw _checked_ exceptions. So if `processLog` can throw an `IOException` then this code will fail to compile. – Slaw Sep 17 '21 at 00:55
  • 1
    And if it can't it wlll also fail to compile. – user207421 Sep 17 '21 at 01:03
-2

My last answer was wrong. Similar question has been asked before.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571