C#使用JsonConvert反序列化Avro文件报字符解析错误如何解决?
问题根因
- 核心逻辑错误:Avro是二进制序列化格式,本身不是明文JSON结构。你直接把二进制Avro文件流转为UTF-8字符串,再传入JsonConvert做反序列化完全不匹配解析逻辑。你遇到的报错开头
O就是Avro文件固定头魔数Obj的首个字符,JSON解析器识别到非JSON格式的首字符直接抛出异常。 - 第三方工具能正常解析是因为工具内置了完整的Avro解析逻辑,会先读取Avro文件头中的Schema定义、解码二进制数据,最后再转换为JSON展示,不代表源Avro文件本身是JSON格式。
正确反序列化方案
C#生态下有成熟的Avro处理库,不需要自己转字符串用JSON解析,推荐两种常用实现:
方案1:使用封装更简单的AvroConvert
- 安装Nuget包:
Install-Package SolTechnology.Avro - 改造你的业务代码如下:
var stream = new MemoryStream(); Uri fileLink = new Uri(gcsLocation); var path = String.Join("", fileLink.Segments, 2, fileLink.Segments.Length - 2); await _storageClient.DownloadObjectAsync(_bucketName, path, stream); // 关键:重置流指针到起始位置,否则读取不到数据 stream.Position = 0; // 直接从二进制流反序列化,无需转字符串 return AvroConvert.Deserialize<T>(stream);
方案2:使用Apache官方Avro库
- 安装Nuget包:
Install-Package Apache.Avro - 需先匹配Avro文件的Schema定义,再调用官方接口解析,适合需要精细控制Schema的场景,示例代码如下:
stream.Position = 0; // 替换为你实际的Avro Schema字符串 var schema = Schema.Parse("你的Avro Schema内容"); var reader = new GenericDatumReader<GenericRecord>(schema, schema); var fileReader = new DataFileReader<GenericRecord>(stream, reader); while (fileReader.MoveNext()) { var record = fileReader.Current; // 按字段名读取record中的值即可 }
注意事项
- 泛型类
T的字段名、字段类型必须和Avro文件的Schema定义完全匹配,否则会出现字段解析失败、缺失的问题 - 不要对二进制Avro流做任何字符串编码转换操作,直接传递原始流给Avro解析库即可,避免编码丢失导致数据损坏
内容的提问来源于stack exchange,提问作者Zichen Ma
相关产品推荐
相关产品推荐

