kotlin - 在 Kotlin 中使用 SAX 进行异步 XML 解析
问题描述
我有一个 SAX 解析器读取 XML 文件(特别是 .xlsx 文件)并将内容作为 Row 对象列表返回:大致是这样的
fun readExcelContent(data: InputStream) {
val pkg = OPCPackage.open(file)
val reader = XSSFReader(pkg)
val sst = reader.sharedStringsTable
val parser = XMLHelper.newXMLReader()
val handler = ExcelSheetHandler(sst)
parser.contentHandler = handler
val sheet = reader.sheetsData.next()
val source = InputSource(sheet)
parser.parse(source)
return handler.content
}
扩展并负责填充列表ExcelSheetHandler
的类在哪里:DefaultHandler
class ExcelSheetHandler(sst: SharedStringsTable): DefaultHandler() {
private val content = mutableListOf<Row>()
@Throws(SAXException::class)
override fun endElement(uri: String?, localName: String?, name: String) {
// If it's the end of a content element, add a row to content
}
}
它基本上是对Apache POI howto中事件模型示例的轻微修改。
我想知道是否有一种方法可以readExcelContent
返回异步对象(例如流),并在读取行后立即将行发送给其客户端,而不必等待整个文件被处理。
解决方案
我更喜欢这个kotlinx.coroutines.Channel
用kotlinx.coroutines.Flow
例,因为这是由该parse()
方法触发的热数据流。以下是Kotlin 语言指南所述的内容。
流是类似于序列的冷流——流构建器中的代码在收集流之前不会运行
这是您可以尝试的快速实现。
class ExcelSheetHandler : DefaultHandler() {
private val scope = CoroutineScope(Dispatchers.Default)
private val rows = Channel<Row>()
override fun endDocument() {
// To avoid suspending forever!
rows.close()
}
@Throws(SAXException::class)
override fun endElement(uri: String?, localName: String?, name: String) {
readRow(uri, localName, name)
}
private fun readRow(uri: String?, localName: String?, name: String) = runBlocking {
// If it's the end of a content element, add a row to content
rows.send(row)
}
// Client code - if it needs to be somewhere else
// you can expose a reference to Channel object
private fun processRows() = scope.launch {
for(row in rows) {
// Do something
println(row)
}
}
}
推荐阅读
- assembly - How do I efficiently do signed comparisons on the 8080?
- sql - 插入触发器后的标识符无效
- r - 如何迭代拟合 brms 回归模型并将均值和 sigma 提取到数据框
- python - 如何在迭代时替换特定的数据框值?
- javascript - 为什么我会收到这个已弃用的警告?!MongoDB
- c# - ASP.NET MVC 5 @Html.Raw 不能使用 ▶
- git - 在 git 合并提交消息中自动包含冲突和已解决的文件
- processing - 如何在保持形状静态而不重新渲染静态形状的情况下使形状移动?
- botframework - 对 MS Graph 进行身份验证时出现 400 错误请求
- php - 使用 php 修改/更改文本文档中的行