我正在使用Akka FileIO(在scala中)创建一个文件解析器,用于从输入文件中读取每一行并应用一个简单的接收器。除了文件中以EOF结尾的最后一行外,每一行都用换行符(' \ n')分隔。
我如何处理换行和自由分隔,这样我才能可靠地读取最后一行,而不必依赖最终的' / n'字符?
var rowNum = 0
val simpleMsgSink: Sink[String, Future[Done]] =
Sink.foreach {
case row: String => {
println(s"$rowNum: $row")
rowNum = rowNum+1
}
}
val source = FileIO.fromPath(file, 1 * 1024 * 1024 )
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 1024))
.map(_.utf8String)
.runWith(simpleMsgSink)
如果对文件执行此操作(最后一行末尾没有换行符):
Sensor_ID,Location,Seqno,gwrx.time,Temp,Humidity,Noise,CO2,Water
A0890,"51.645368, 0.072211",1,42793.00278,16,48,36,325,0
A0891,"51.645370, 0.072300",1,42793.00278,15,41,34,353,3
输出结果为:
0: Sensor_ID,Location,Seqno,gwrx.time,Temp,Humidity,Noise,CO2,Water
1: A0890,"51.645368, 0.072211",1,42793.00278,16,48,36,325,0
如何拾取最后一行?
答案 0 :(得分:0)
如果您查看Framing.delimiter
的{{3}},您会看到它实际上有第三个参数:allowTruncation
,默认值为false
。这就是scaladoc所说的:
如果是
false
,那么当被解码的最后一帧不包含有效的分隔符时,此流将使流失败而不是返回截断的帧。
所以你需要做的就是添加缺少的参数:
Framing.delimiter(ByteString("\n"), maximumFrameLength = 1024, allowTruncation = true)