使用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));
}
同样的错误信息。
发布于 2017-06-12 10:15:11
Supplier
并不神奇,你仍然需要从供应商那里提供一个新的流。
所以你可以:
Supplier<Stream<String>> supplier = () -> Files.lines(Paths.get(fileName));
但这意味着要一直读文件。您可以将所有行读入单个List
中,并将其存储在内存中,并将其从stream
中提取出来。
List<String> allLines = Files.readAllLines(Paths.get(fileName));
Supplier<Stream<String>> supplier = () -> allLines.stream();
请注意,即使您所链接的教程也返回了一个新的流,它是通过Stream.of
创建的,如下所示:
Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);
发布于 2017-06-12 10:11:12
这是因为您的供应商总是提供相同的Stream
实例,并且您已经使用了findFirst()
。然后尝试使用findFirst()
再次使用它,这是不允许的。
在本教程中,每次创建一个新的流。在您的示例中,您必须调用供应商内部的Files.lines()
才能使其工作,尽管这意味着您每次都要重新读取该文件。
https://stackoverflow.com/questions/44506038
复制相似问题