从GenericRecord中提取ByteBuffer有时会有额外的值

时间:2017-07-05 01:14:44

标签: scala avro

我在spark中将对象序列化为avro格式。这些对象包括字节数组(编辑:polylines,表示为字符串)。当我检查文件时,数据是正确的。

$ java -jar ~/data/avro-tools-1.8.1.jar tojson part-00000.avro | grep 123
{"key":123, "data":{"bytes":"gt_upA`mjrcE{Cw^uBwY"}}
# ^ this example has been simplified for this question

gt_upA`mjrcE{Cw^uBwY是字节数组的正确字符串表示形式。

然后我尝试在我的普通Scala应用程序中反序列化这些文件。大多数值都被正确解析,但有时在解析的数组中有额外的字节。

val entity: GenericRecord
val byteBuffer = entity.get("data").asInstanceOf[ByteBuffer]
println(new String(byteBuffer.array, "UTF-8"))

gt_upA`mjrcE{Cw^uBwYB中的结果。请注意额外的尾随B

我正在并行解析文件,我猜ByteBuffer实例不是线程安全的,并且正在覆盖支持数组。

我应该如何解析这些文件?

编辑:问题就在于,我已经将值直接编码为UTF-8字符串。它在解析时增加了额外的工作,但避免了ByteBuffer无法同时读取的问题。

1 个答案:

答案 0 :(得分:0)

您无法将任意二进制数据打印为UTF-8。某些字节组合无效或不明确,将它们转换为字符并不是很好定义,并且取决于您使用的库(以及终端设置)。

只需将它们打印为十六化合物:

byteBuffer.array.foreach { b => print("%02X".format(b)) }
println