Is there any way for reading two or more files in one Java8-stream?

前端 未结 3 1387
無奈伤痛
無奈伤痛 2021-01-02 21:52

I like new Java8 StreamAPI and want use it not only for one file. As usually, I use this code:

Stream lines = Files.lines(Paths.get(\"/somepat         


        
相关标签:
3条回答
  • 2021-01-02 22:14

    You can use following code

    Files.list(Paths.get("path"))
                .filter(Files::isRegularFile)
                .flatMap(s -> {
                    try {
                        return Files.lines(s);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return null;
                })
                .forEach(System.out::println);
    
    0 讨论(0)
  • 2021-01-02 22:21

    Without any extra helper functions or outside libraries, the easiest is:

    Stream<String> lines1 = Files.lines(Paths.get("/somepathtofile"));
    Stream<String> lines2 = Files.lines(Paths.get("/somepathtoanotherfile"));
    
    Stream.concat(lines1, lines)
        .filter(...)
        .forEach(...);
    

    If Files.lines hadn't been declared to throw a checked exception, you'd be able to do

    Stream.of("/file1", "/file2")
         .map(Paths::get)
         .flatMap(Files::lines)....
    

    But, alas, we can't do that. There are several workarounds. One is to make your own version of Files.lines that calls the standard one, catches IOException and rethrows as an UncheckedIOException. Another approach is a more general way to make functions out of methods that throw checked exceptions. It would look something like this:

    @FunctionalInterface
    public interface ThrowingFunction<T,R> extends Function<T,R> {
    
        @Override
        public default R apply(T t) {
            try {
                return throwingApply(t);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static<T,R> Function<T,R> wrap(ThrowingFunction<T,R> f) {
            return f;
        }
    
        R throwingApply(T t) throws Exception;
    }
    

    and then

    Stream.of("/somefile", "/someotherfile", "/yetanotherfile")
            .map(Paths::get)
            .flatMap(ThrowingFunction.wrap(Files::lines))
            .....
    

    There are several libraries out there that went through the trouble of writing something like the above out for every functional interface.

    0 讨论(0)
  • 2021-01-02 22:32

    With cyclops-streams (a library we have created) you can write

      SequenceM.of("/somepathtofile1","/somepathtofile2")
                 .flatMapFile(File::new)
                 .forEach(System.out::println);
    

    Javadoc SequenceM extends java.util.stream.Stream (and also org.jooq.lambda.Seq) to add a lot of additional convenience methods.

    0 讨论(0)
提交回复
热议问题