我有一个以JSON格式编写的Schema。我从kafka服务器获得一个字符串,如下所示:
\ 0 \ 0 \ 0 \ u00032H45d71580-9781-4d9c-8535-a233ff7c3122 \ nPLANTH45d71580-9781-4d9c-8535-a233ff7c3122 \ nPLANT,2017-12-12T16:34:15GMT \ u001020171212 \ u0018201712121034 \ nthertH1AB5297A-9D28- 4742-A95C-4A4CEED7037D \ nfalse \ nfalse \ ncross \ u00021 \ u00025
现在我尝试反序列化字符串并根据我的Schema文件将其设置为Object。我怎么能在c#中做到这一点?有没有我可以使用的图书馆?
我试过Microsoft.Hadoop.Avro。 https://docs.microsoft.com/en-us/azure/hdinsight/hadoop/apache-hadoop-dotnet-avro-serialization#Scenario1 一旦代码运行到:
$config['sess_save_path'] = APPPATH . 'sessions';
它会引发异常: “阵列尺寸超出了支持的范围”
我从kafka获得了字符串。另一个应用程序产生它,我的应用程序使用它应用程序生成它是用swift编写的,他们使用一些nodejs lib来进行序列化。所以我想如果字符串的格式很重要吗?
kafka消息由Javascript应用程序生成。他们使用名为AVSC的库(Avro for Javascript)序列化字符串。一旦我得到消息(字符串),我将其转换为字节流,之后我发现这个字节与AVSC lib生成的原始字节略有不同。但为什么呢?
答案 0 :(得分:2)
Confluent的Java库(我怀疑是Swift应用程序用来写入Kafka的)在序列化为Avro的二进制编码时会写一个魔术字节。请参阅此文章:https://docs.confluent.io/current/schema-registry/docs/serializer-formatter.html#wire-format
他们将其用于版本控制和向后兼容性,详情请参阅:https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-Messagesets
但是,Microsoft.Hadoop.Avro你正在使用的库在de / serializes时不使用魔术字节。尝试在调用Deserialize()之前从流中删除第一个字节。
答案 1 :(得分:2)
您可以尝试使用https://github.com/AdrianStrugala/AvroConvert
如果Kafka中的文件仅包含数据,请使用:
var actual = AvroCnvert.DeserializeHeadless<TheModel>(buffer, schema);
您需要确保模型和架构正确。
Avro是一种数据格式(完全类似于JSON)。每种序列化程序的实现(或语言)都应该相互兼容。
答案 2 :(得分:0)
你应该尝试Microsoft.Hadoop.Avro.Container.AvroContainer这有一个方法CreateGenericReader。喜欢的东西;
using (var reader = AvroContainer.CreateGenericReader(buffer))
{
while (reader.MoveNext())
{
foreach (dynamic record in reader.Current.Objects) {
// Take a look at what you get in the record
}
}
}
Nuget包是Microsoft.Avro.Tools(.Net Core中的v0.1.0)