我在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无法同时读取的问题。
答案 0 :(得分:0)
您无法将任意二进制数据打印为UTF-8。某些字节组合无效或不明确,将它们转换为字符并不是很好定义,并且取决于您使用的库(以及终端设置)。
只需将它们打印为十六化合物:
byteBuffer.array.foreach { b => print("%02X".format(b)) }
println