使用 JUnit
和 Stream
时出现以下错误消息:
java.lang.IllegalStateException: stream has already been operated upon or closed
我做了一个研究,很明显不可能重用流
但是根据这篇文章:
与 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());
}
你怎么看我使用 supplier.get()
来处理 Stream
(它与教程一致),但是@Test
打印到 B,因此 @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));
}
同样的错误信息。
最佳答案
Supplier
并不神奇,您仍然需要始终从该 Supplier 提供一个新流。
所以你可以这样做:
Supplier<Stream<String>> supplier = () -> Files.lines(Paths.get(fileName));
但这意味着要一直读取文件。您可以将所有行读入单个 List
,将其存储在内存中并从中流
。
List<String> allLines = Files.readAllLines(Paths.get(fileName));
Supplier<Stream<String>> supplier = () -> allLines.stream();
请注意,即使是您链接的教程也会返回一个新的 Stream,它是通过 Stream.of
创建的,如下所示:
Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);
关于Java 8 : Supplier working with files throws "stream has already been operated upon or closed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44506038/