首页 > 解决方案 > Apache Avro C# GenericFixed Encoding 抛出“AvroException:GenericFixed 需要针对固定模式进行写入,但发现 Avro.Generic.GenericFixed”

问题描述

在 C# 中使用 Avro GenericRecord sdk 时,我在“specDataWriter.Append(exampleRecorder);”行出现错误“ AvroException: GenericFixed required to write against fixed schema but found Avro.Generic.GenericFixed ” 尝试对固定类型记录进行编码时。其余类型工作正常。

Apache.Avro lib 版本是最新的 1.10.2

这样做的正确方法是什么?

        static byte[] Encode()
        {
            string schemaSx = @"
{
    'namespace': 'example.avro',
    'type': 'record',
    'name': 'User',
    'fields': [{
            'name': 'arrayOfRecord',
            'type': {
                'type': 'array',
                'items': {
                    'type': 'record',
                    'name': 'Inner',
                    'fields': [{
                            'name': 'innerInt',
                            'type': 'int'
                        }
                    ]
                }
            }
        }, {
            'name': 'arrayOfInt',
            'type': {
                'type': 'array',
                'items': 'int'
            }
        }, {
            'name': 'mapOfRecord',
            'type': {
                'type': 'map',
                'values': {
                    'type': 'record',
                    'name': 'MapInner',
                    'fields': [{
                            'name': 'innerIntx',
                            'type': 'int'
                        }
                    ]
                }
            }
        }, {
            'name': 'mapOfInt',
            'type': {
                'type': 'map',
                'values': 'int'
            }
        }, {
            'name': 'booleanType',
            'type': 'boolean'
        }, {
            'name': 'intType',
            'type': 'int'
        }, {
            'name': 'longType',
            'type': 'long'
        }, {
            'name': 'floatType',
            'type': 'float'
        }, {
            'name': 'doubleType',
            'type': 'double'
        }, {
            'name': 'bytesType',
            'type': 'bytes'
        }, {
            'name': 'stringType',
            'type': 'string'
        }, {
            'name': 'fixedType',
            'type': {'type' : 'fixed' , 'name' : 'fixedTypeData', 'size' : 1}
        }
    ]
}
";

            using (var ms = new MemoryStream())
            {
                RecordSchema schema = RecordSchema.Parse(schemaSx) as RecordSchema;

                RecordSchema schemaInner = RecordSchema.Parse("{'type':'record','name':'Inner','fields':[{'name':'innerInt','type':'int'}]}") as RecordSchema;
                RecordSchema mapSchemaInner = RecordSchema.Parse("{'type':'record','name':'Inner','fields':[{'name':'innerIntx','type':'int'}]}") as RecordSchema;

                var exampleRecorderInner = new GenericRecord(schemaInner);
                exampleRecorderInner.Add("innerInt", 1);
                var exampleRecorderInner2 = new GenericRecord(schemaInner);
                exampleRecorderInner2.Add("innerInt", 2);
                GenericRecord[] arrayOfRecord = { exampleRecorderInner, exampleRecorderInner2 };

                //Passing in schema object to get a record object
                int[] arrayOfInt = new int[] { 252, 2, 56, 8, 9, 251 };
                byte[] bytes = new byte[] { 252, 2, 56, 8, 9, 251 };

                Dictionary<String, int> mapOfInt = new Dictionary<string, int>();
                mapOfInt["a"] = 1;
                mapOfInt["b"] = 2;

                Dictionary<String, GenericRecord> mapOfRecord = new Dictionary<string, GenericRecord>();
                var mapRecorderInner = new GenericRecord(mapSchemaInner);
                mapRecorderInner.Add("innerIntx", 1);
                var mapRecorderInner2 = new GenericRecord(mapSchemaInner);
                mapRecorderInner2.Add("innerIntx", 2);

                mapOfRecord["c"] = mapRecorderInner;
                mapOfRecord["d"] = mapRecorderInner2;

                FixedSchema fixedSchema = FixedSchema.Parse("{'type' : 'fixed' , 'name' : 'fixedTypeData', 'size' : 1}") as FixedSchema;
                byte[] fixedValue = new byte[] { 252 };
                GenericFixed fixedRecord = new GenericFixed(fixedSchema);
                fixedRecord.Value = (byte[])fixedValue;

                var exampleRecorder = new GenericRecord(schema);
                
                exampleRecorder.Add("arrayOfRecord", arrayOfRecord);
                exampleRecorder.Add("arrayOfInt", arrayOfInt);
                exampleRecorder.Add("mapOfInt", mapOfInt);
                exampleRecorder.Add("mapOfRecord", mapOfRecord);
                exampleRecorder.Add("booleanType", true);
                exampleRecorder.Add("intType", 1);
                exampleRecorder.Add("longType", 1L);
                exampleRecorder.Add("floatType", 1.0f);
                exampleRecorder.Add("doubleType", 1.0d);
                exampleRecorder.Add("bytesType", bytes);
                exampleRecorder.Add("stringType", "1");
                exampleRecorder.Add("fixedType", fixedRecord);

                var specDatumWriter = new GenericDatumWriter<GenericRecord>(schema);
                var specDataWriter = Avro.File.DataFileWriter<GenericRecord>.OpenWriter(specDatumWriter, ms);
                specDataWriter.Append(exampleRecorder);
                specDataWriter.Flush();
                specDataWriter.Close();
                return ms.ToArray();
            }

标签: c#avro

解决方案


推荐阅读