gpt4 book ai didi

java - 如何用 Java 或 Kotlin 解析大型 YAML 文件?

转载 作者:行者123 更新时间:2023-12-05 05:30:03 40 4
gpt4 key购买 nike

我有一个很大的 YAML 文件(~5MB),我需要使用 Kotlin/JVM 解析它。

我尝试使用 Jackson 2.14.1 的流式 API,但它抛出:

com.fasterxml.jackson.dataformat.yaml.JacksonYAMLParseException: The incoming YAML document exceeds the limit: 3145728 code points.
at [Source: (ZipInputStream); line: 122415, column: 9]
...
Caused by: org.yaml.snakeyaml.error.YAMLException: The incoming YAML document exceeds the limit: 3145728 code points.

我的 YAML 文件是一个大字典,大约有 5k 个键,每个键都关联一个小文档。我流式传输根 key 并使用 JsonParser.readValueAs() 解析每个关联文档方法。因为我是流媒体,所以我希望字典的大小不会有问题,只要每个子文档足够小。但是,有。我在第 122415 行检查了无法解析的文档,它既不大(1.5KB)也不格式错误(根据 https://www.yamllint.com/ )。

我的代码是:

@Service
class Parser(
@Qualifier("yamlMapper") private val yamlMapper: ObjectMapper,
) {
fun parse(input: InputStream): Flow<Item> = flow {
val parser = yamlMapper.factory.createParser(input)
parser.use {
parser.requireToken(JsonToken.START_OBJECT)
var token = parser.nextToken()
while (token != JsonToken.END_OBJECT) {
if (token != JsonToken.FIELD_NAME) {
throw JsonParseException(parser, "Expected FIELD_NAME but was $token")
}
parser.requireToken(JsonToken.START_OBJECT)
emit(parser.readValueAs(Item::class.java))
token = parser.nextToken()
}
parser.requireToken(null)
}
}
}

fun JsonParser.requireToken(expected: JsonToken?) {
val actual = nextToken()
if (actual != expected) {
throw JsonParseException(this, "Expected ${expected ?: "end of file"} but was $actual")
}
}

最佳答案

在翻阅 Jackson 的文档后,发现这很容易。我需要在创建 ObjectMapper 时配置 YAMLFactory:

@SpringBootApplication
class Main {
@Bean
fun yamlMapper(): ObjectMapper =
ObjectMapper(YAMLFactory.builder()
.loaderOptions(LoaderOptions().apply {
codePointLimit = 100 * 1024 * 1024 // 100MB
})
)
}

参见 Maximum input YAML document size (3 MB) .

关于java - 如何用 Java 或 Kotlin 解析大型 YAML 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74805240/

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