我想在 Kotlin 脚本中使用 Java Web 套接字 API 接收 HTTP 请求。我在请求中只需要两行,所以我尝试将整个请求作为字符串行获取,对其进行迭代,并为这两行中的每一行获取与正则表达式匹配的行。我测试了一个文本文件的 FileInputStream,而不是从客户端发送的实际 InputStream。我只能迭代一次,所以我无法获得第二行。我收到以下结果。获取/hello.html HTTP/1.1线程“main”中的异常 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 接口,但这不起作用。我之前尝试过同样的事情并且它有效。我现在正在重写代码,因为以前的版本有点乱。
2 回答
翻阅古今
TA贡献1780条经验 获得超5个赞
因为在第一次调用时linesSupplier.get()你消耗了inputStream并且在第二次调用时它抛出异常。不要使用供应商,只需定义一个法线Sequence并使用它:
val lines: Sequence<String> = inputStream.bufferedReader().lines().asSequence()
//...
path = filterLines(lines, regexGet)
//...
host = filterLines(lines, regexHost)
RISEBY
TA贡献1856条经验 获得超5个赞
表示惰性评估集合的序列类型。用于实例化序列的顶级函数和序列的扩展函数。
对于没有供应商的解决方案:如文档所述,序列尝试延迟评估由 inputStream 的“lines”方法返回的流中的值。所以第一次调用它会读取流,第二次调用尝试做同样的事情会失败,因为你不能读取流两次。您可以使用 toList 而不是 asSequence 来解决它。List 会读取一次并保存在内存中。如果您不受内存限制,它将解决您的问题。
val linesSupplier: List<String> = inputStream.bufferedReader().lines().toList()
编辑:对于与供应商的解决方案:您应该能够通过将文件流的创建移动到供应商来使其工作。在您的代码段中,供应商失败,因为您使用的是已经消耗的相同流。
val linesSupplier: Supplier<Sequence<String>> = Supplier { FileInputStream("C:\\test.txt").bufferedReader().lines().asSequence() }
添加回答
举报
0/150
提交
取消