Supplier<Sequence<String>> 不能迭代多次

我想在 Kotlin 脚本中使用 Java Web 套接字 API 接收 HTTP 请求。

我在请求中只需要两行,所以我尝试将整个请求作为字符串行获取,对其进行迭代,并为这两行中的每一行获取与正则表达式匹配的行。

我测试了一个文本文件的 FileInputStream,而不是从客户端发送的实际 InputStream。我只能迭代一次,所以我无法获得第二行。我收到以下结果。

获取/hello.html HTTP/1.1

线程&ldquo;main&rdquo;中的异常 java.util.NoSuchElementException:序列不包含与谓词匹配的元素。在 RequestParam$filterLines$1.invoke(RequestParam.kt:29) 在 RequestParam$filterLines$1.invoke(RequestParam.kt:6) 在 RequestParam.(RequestParam.kt:19) 在 RequestParamKt.main(RequestParam.kt:26)

官方 Kotlin 参考资料说,由 asSequence() 实例化的序列不能迭代多次。所以我使用了 Supplier 接口,但这不起作用。

我之前尝试过同样的事情并且它有效。我现在正在重写代码,因为以前的版本有点乱。


慕慕森
浏览 92回答 2
2回答

翻阅古今

因为在第一次调用时linesSupplier.get()你消耗了inputStream并且在第二次调用时它抛出异常。不要使用供应商,只需定义一个法线Sequence并使用它:val lines: Sequence<String> =&nbsp; inputStream.bufferedReader().lines().asSequence()//...path = filterLines(lines, regexGet)//...host = filterLines(lines, regexHost)

RISEBY

表示惰性评估集合的序列类型。用于实例化序列的顶级函数和序列的扩展函数。对于没有供应商的解决方案:如文档所述,序列尝试延迟评估由 inputStream 的“lines”方法返回的流中的值。所以第一次调用它会读取流,第二次调用尝试做同样的事情会失败,因为你不能读取流两次。您可以使用 toList 而不是 asSequence 来解决它。List 会读取一次并保存在内存中。如果您不受内存限制,它将解决您的问题。val&nbsp;linesSupplier:&nbsp;List<String>&nbsp;=&nbsp;inputStream.bufferedReader().lines().toList()编辑:对于与供应商的解决方案:您应该能够通过将文件流的创建移动到供应商来使其工作。在您的代码段中,供应商失败,因为您使用的是已经消耗的相同流。val&nbsp;linesSupplier:&nbsp;Supplier<Sequence<String>>&nbsp;=&nbsp;Supplier&nbsp;{&nbsp;FileInputStream("C:\\test.txt").bufferedReader().lines().asSequence()&nbsp;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java