Java 8:使用文件的供应商抛出"流已经被操作或关闭"

Man*_*dan 1 java java-8 java-stream

使用JUnitStream我有以下错误消息:

java.lang.IllegalStateException: stream has already been operated upon or closed
Run Code Online (Sandbox Code Playgroud)

我做了一个研究,可以明确的是没有可能重用流

根据这篇文章:

使用Supplier是可以解决这个问题.

所以我目前的代码如下:

    try (Stream<String> stream =  Files.lines(Paths.get(fileName)) ) {

        Supplier<Stream<String>> supplier = () -> stream;

        logger.info("A");
        logger.info("ABC {}", supplier.get().findFirst().get());
        logger.info("B");
        logger.info("XYZ {}", supplier.get().skip(1050).findFirst().get());
        logger.info("C");

        assertThat(supplier.get().count(), is(1051));

    }
    catch (IOException e) {
        logger.error("{}", e.getMessage());
    }
Run Code Online (Sandbox Code Playgroud)

怎么可以看到我用的是supplier.get()与工作Stream(其与本教程根据),但@Test打印,直到,因此@Test在出现故障supplier.get().skip(1050).findFirst().get(),它仍产生相同的错误消息.

我的代码和教程之间的独特区别,mime通过文件工作,教程围绕数组工作.

有什么特别的编辑工作没有任何问题?

Α

我做了以下版本(根据Eugene的代码段)

   try (Stream<String> stream =  Files.lines(Paths.get(fileName)) ) {

        Supplier<Stream<String>> supplier = () -> stream.collect(Collectors.toList()).stream();

        logger.info("A");
        logger.info("ABC {}", supplier.get().findFirst().get());
        logger.info("B");
        logger.info("XYZ {}", supplier.get().skip(1050).findFirst().get());
        logger.info("C");

        assertThat(supplier.get().count(), is(1051));

    }
Run Code Online (Sandbox Code Playgroud)

相同的错误消息.

Eug*_*ene 7

Supplier没有什么神奇之处,您仍需要始终从该供应商处提供新的Stream.

所以你可以这样做:

Supplier<Stream<String>> supplier = () -> Files.lines(Paths.get(fileName));
Run Code Online (Sandbox Code Playgroud)

但这意味着要一直读取文件.你可以把所有的行都读成一个单独的List存储区,然后存储在内存stream中.

List<String> allLines = Files.readAllLines(Paths.get(fileName));

Supplier<Stream<String>> supplier = () -> allLines.stream();
Run Code Online (Sandbox Code Playgroud)

请注意,即使您链接的教程也会返回一个新的Stream,通过Stream.of如下方式创建:

 Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用`Files.readAllLines(...)`直接返回一个列表. (4认同)
  • @ManuelJordan你一直在使用和使用相同的`stream`. (2认同)
  • @ManuelJordan当你不止一次重用lambda时,你不能在lambda中重用一个流. (2认同)