kotlin - 生成序列时抛出的异常
问题描述
我想将一个可能很大的文件从一个地方复制到另一个地方(例如但不限于本地文件系统)。为了将阅读与写作分离,我的复制流程包含执行每个任务的步骤:
- 读取步骤返回一系列行(文件内容)。此步骤生成文件的每一行以避免将所有文件内容都放在内存中。
- 写入步骤写入从上一步接收到的行序列。
好吧,有时读取文件时可能会发生异常,在这种情况下,我希望捕获该异常并返回空的行序列。我一直在阅读如何进行,但我只找到与协程相关的参考资料。并且sequence
生成器不是协程的。
编辑:正如评论中所建议的,我避免使用 Either。尽管如此,在文件读取期间可能会引发 IOException。
最后,我以此结束:
import arrow.syntax.function.compose
import arrow.syntax.function.pipe
import java.io.IOException
import java.io.InputStream
fun asSequenceOfLines(stream: InputStream): Sequence<String> =
sequence {
stream.bufferedReader().use {
// readLine() can throw a IOException during file reading
var line = it.readLine()
while (line != null) {
yield(line)
line = it.readLine()
}
}
}
// A step for reading a file given its path
fun readFile(): FlowStep = { data ->
val path = data["input"] as String
val inputStream = File(path).inputStream()
try {
val lines = asSequenceOfLines(inputStream)
data + mapOf("lines" to lines)
} catch (e: Exception) {
// [!] NOT catched exception
println("[WARN] Error when reading file content $path")
data + mapOf("lines" to emptySequence<String>())
}
}
当调用此函数并抛出异常时,我无法捕获它,因为它是在消耗序列时抛出的(通常在编写步骤中)。如何在asSequenceOfLines()
调用函数(读取步骤)中捕获异常?
你在这里有完整的代码:https ://pastebin.com/PCarVGP8 。我正在使用 Kotlin 1.3.50 和 arrow-kt 0.10.0。
谢谢阅读 :)
解决方案
而且序列生成器不是协程的
实际上,它是……但在这种情况下并不重要。
好吧,有时读取文件时可能会发生异常,在这种情况下,我希望捕获该异常并返回空的行序列
你知道 Kotlin 中的序列是如何工作的以及它们是什么吗?Sequence
是一种使收集处理变得懒惰的抽象。asSequenceOfLines
不是阅读步骤。它只是创建了这个抽象。asSequenceOfLines
调用函数时读取零行。所以,IOException
不能在那个电话上被抛出。
实际读取发生在序列被消耗时。但是 Kotlin 序列无法预测未来,并在一开始就说会有一条IOException
第 100500 行。所以,当发生的时候IOException
,一些行已经被消耗掉了,并且序列已经不是空的了!
如果您无法提前读取所有文件并将其保存在内存中,则需要在写入步骤中处理此异常并恢复所有部分完成的写入工作。
此外,还有一种stdlib 方法可以逐行读取(和处理)文本文件。
推荐阅读
- java - 如何在 android studio 3.1.1 中引入默认的 pdf 开启器选项
- android - 我的应用程序中的 Viewpager Activity 重新启动
- liquibase - 如何在 Liquibase 中生成 SQL 执行日志
- sql - 如何在多维数据集中选择最大日期并存储在 plsql 存储过程的变量中
- php - mysql 中的日期字段未从 php/html 表单更新
- javascript - 通过对象键合并键从多个对象创建数组
- debugging - 如何通过命令行将 XML 文件导入“Charles Proxy > Map Local”
- r - 使用纬度和经度误差计算距离
- jquery - 使用jquery将变量及其值从一个html页面传递到另一个html页面
- linux - 如何使用 wget 从 github 下载包含多个文件的文件夹?