为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕慕森 2023-06-08 17:23:54
我想在 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 接口,但这不起作用。我之前尝试过同样的事情并且它有效。我现在正在重写代码,因为以前的版本有点乱。
查看完整描述

2 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

因为在第一次调用时linesSupplier.get()你消耗了inputStream并且在第二次调用时它抛出异常。不要使用供应商,只需定义一个法线Sequence并使用它:


val lines: Sequence<String> =  inputStream.bufferedReader().lines().asSequence()


//...


path = filterLines(lines, regexGet)


//...


host = filterLines(lines, regexHost)


查看完整回答
反对 回复 2023-06-08
?
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() }



查看完整回答
反对 回复 2023-06-08
  • 2 回答
  • 0 关注
  • 91 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信