gpt4 book ai didi

java - Supplier> 不能迭代多次

转载 作者:行者123 更新时间:2023-12-02 12:46:34 26 4
gpt4 key购买 nike

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

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

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

GET /hello.html HTTP/1.1

Exception in thread "main" java.util.NoSuchElementException: Sequence contains no element matching the predicate. at RequestParam$filterLines$1.invoke(RequestParam.kt:29) at RequestParam$filterLines$1.invoke(RequestParam.kt:6) at RequestParam.(RequestParam.kt:19) at RequestParamKt.main(RequestParam.kt:26)

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

我以前试过同样的东西,它奏效了。我现在正在重写代码,因为以前的版本有点乱。之前的版本是here

下面是我正在努力使用的当前版本。

import java.io.FileInputStream
import java.io.InputStream
import java.util.function.Supplier
import kotlin.streams.asSequence

class RequestParam(private val inputStream: InputStream) {
val path: String
val host: String

init {
//I'd like to receive request from client as multiple lines of String.
//I generated Supplier since instance made by asSequence() cannot be iterated more than once https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/index.html
val linesSupplier: Supplier<Sequence<String>> = Supplier { inputStream.bufferedReader().lines().asSequence() }

//I only need lines starting with "GET" or "Host:"
val regex = { x: String -> { y: String -> y.matches(Regex(x)) } }
val regexGet = regex("GET.*")
val regexHost = regex("Host:.*")

//Iterate supplier and get the first line that matches each regex
val filterLines = { x: Sequence<String>, y: (String) -> Boolean -> x.first(y) }
path = filterLines(linesSupplier.get(), regexGet)
println(path) //works fine
host = filterLines(linesSupplier.get(), regexHost)
println(host) // no good
}
}

fun main(args: Array<String>) {
//Test with some file
val inputStream = FileInputStream("C:\\path\\to\\my\\test.txt")
val requestParam = RequestParam(inputStream)
}

和我在测试中使用的文本文件

GET /hello.html HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.barfoo.com
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

为什么我不能多次迭代 linesSupplier?

最佳答案

Sequence type that represents lazily evaluated collections. Top-level functions for instantiating sequences and extension functions for sequences.

对于没有供应商的解决方案:如文档所述,序列尝试延迟评估由 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() }

关于java - Supplier<Sequence<String>> 不能迭代多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57535225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com