gpt4 book ai didi

scala - 如何使用 GenericRecordBuilder 设置记录数组

转载 作者:行者123 更新时间:2023-12-04 17:37:02 24 4
gpt4 key购买 nike

我正在尝试将 Scala 对象(即案例类)转换为字节数组。

为此,我使用其特定模式将对象内容插入到 GenericRecordBuilder 中,并最终使用 GenericDatumWriter 将其转换为字节数组。

我可以毫无问题地将原始类型和原始类型数组设置到 GenericRecordBuilder 中。

但是,我需要帮助将记录数组插入 GenericRecordBuilder,并从中创建一个字节数组。

将记录数组插入 GenericRecordBuilder 的正确方法是什么?

这是我正在尝试做的一部分:

这是架构:

{
"type": "record",
"name": "test1",
"namespace": "ns",
"fields": [
{
"name": "t_name",
"type": "string",
"default": "a"
},
{
"name": "t_num",
"type": "int",
"default": 0
},
{"name" : "t_arr", "type":
["null",
{"type": "array", "items": {
"name": "t_arr_a",
"type": "record",
"fields": [
{
"name": "t_arr_f1",
"type": "int",
"default": 0
},
{
"name": "t_arr_f2",
"type": "int",
"default": 0
}
]
}
}
]
}
]
}

这是填充 GenericRecordBuilder 并将其转换为字节数组的 Scala 类:

package utils

import java.io.ByteArrayOutputStream

import org.apache.avro.{Schema, generic}
import org.apache.avro.generic.{GenericData, GenericDatumWriter}
import org.apache.avro.io.EncoderFactory
import org.apache.avro.generic.GenericRecordBuilder

object CheckRecBuilder extends App {

val avroSchema: Schema = new Schema.Parser().parse(this.getClass.getResourceAsStream("/data/myschema.avsc"))
val recordBuilder = new GenericRecordBuilder(avroSchema)

recordBuilder.set("t_name", "X")
recordBuilder.set("t_num", 100)


recordBuilder.set("t_arr", ???)

val record = recordBuilder.build()


val w = new GenericDatumWriter[GenericData.Record](avroSchema)
val outputStream = new ByteArrayOutputStream()
val e = EncoderFactory.get.binaryEncoder(outputStream, null)
w.write(record, e)
val barr = outputStream.toByteArray

println("End")

}

最佳答案

我设法设置了对象数组。

我想知道是否有更好或更正确的方法。

这是我做的:

  1. 创建了一个案例类:

case class t_arr_a(t_arr_f1:Int, t_arr_f2:Int)

  1. 创建了一个将案例类转换为 GenericData.Record 的方法:

def caseClassToGenericDataRecord(cc:Product, schema:Schema): GenericData.Record = {
val childRecord = new GenericData.Record(schema.getElementType)<br/>
val values = cc.productIterator
cc.getClass.getDeclaredFields.map(f => childRecord.put(f.getName, values.next ))
childRecord
}

  1. 更新了上面的 CheckRecBuilder 类:

替换:

recordBuilder.set("t_arr", ???)

与:

  val childSchema = new GenericData.Record(avroSchema2).getSchema.getField("t_arr").schema().getTypes().get(1)
val tArray = Array(t_arr_a(2,4), t_arr_a(25,14))
val tArrayGRecords: util.List[GenericData.Record]
= Some(yy.map(x => caseClassToGenericDataRecord(x,childSchema))).map(arr => java.util.Arrays.asList(arr: _*)).orNull

recordBuilder.set("t_arr", tArrayGRecords)

关于scala - 如何使用 GenericRecordBuilder 设置记录数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56320410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com