c# - 使用 C# 反序列化 Avro 文件

标签 c# azure hadoop avro

我找不到使用 C# 反序列化 Apache Avro 文件的方法。 Avro 文件是由Archive feature 生成的文件。在 Microsoft Azure 事件中心。

通过 Java,我可以使用 Avro Tools从 Apache 将文件转换为 JSON:

java -jar avro-tools-1.8.1.jar tojson --pretty inputfile > output.json

使用 NuGet 包 Microsoft.Hadoop.Avro 我能够提取 SequenceNumber , OffsetEnqueuedTimeUtc ,但因为我不知道 Body 使用什么类型抛出异常。我尝试过 Dictionary<string, object>和其他类型。

static void Main(string[] args)
{
    var fileName = "...";

    using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        using (var reader = AvroContainer.CreateReader<EventData>(stream))
        {
            using (var streamReader = new SequentialReader<EventData>(reader))
            {
                var record = streamReader.Objects.FirstOrDefault();
            }
        }
    }
}

[DataContract(Namespace = "Microsoft.ServiceBus.Messaging")]
public class EventData
{
    [DataMember(Name = "SequenceNumber")]
    public long SequenceNumber { get; set; }

    [DataMember(Name = "Offset")]
    public string Offset { get; set; }

    [DataMember(Name = "EnqueuedTimeUtc")]
    public string EnqueuedTimeUtc { get; set; }

    [DataMember(Name = "Body")]
    public foo Body { get; set; }

    // More properties...
}

架构如下所示:

{
  "type": "record",
  "name": "EventData",
  "namespace": "Microsoft.ServiceBus.Messaging",
  "fields": [
    {
      "name": "SequenceNumber",
      "type": "long"
    },
    {
      "name": "Offset",
      "type": "string"
    },
    {
      "name": "EnqueuedTimeUtc",
      "type": "string"
    },
    {
      "name": "SystemProperties",
      "type": {
        "type": "map",
        "values": [ "long", "double", "string", "bytes" ]
      }
    },
    {
      "name": "Properties",
      "type": {
        "type": "map",
        "values": [ "long", "double", "string", "bytes" ]
      }
    },
    {
      "name": "Body",
      "type": [ "null", "bytes" ]
    }
  ]
}    

最佳答案

我能够使用动态获得完整的数据访问。以下是访问原始 body 数据的代码,该数据存储为字节数组。就我而言,这些字节包含 UTF8 编码的 JSON,但这当然取决于您最初如何创建发布到事件中心的 EventData 实例:

using (var reader = AvroContainer.CreateGenericReader(stream))
{
    while (reader.MoveNext())
    {
        foreach (dynamic record in reader.Current.Objects)
        {
            var sequenceNumber = record.SequenceNumber;
            var bodyText = Encoding.UTF8.GetString(record.Body);
            Console.WriteLine($"{sequenceNumber}: {bodyText}");
        }
    }
}

如果有人可以发布静态类型的解决方案,我会投票赞成它,但考虑到任何系统中更大的延迟几乎肯定是与事件中心存档 blob 的连接,我不会担心解析性能。 :)

关于c# - 使用 C# 反序列化 Avro 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39846833/

相关文章:

mysql - Hadoop(+HBase/HDFS)与 Mysql(或 Postgres)——要处理和查询的独立结构化数据负载

docker - 使用数据初始化 Cloudera Hive Docker 容器

c# - PHP-C#双向通信

azure - 从 Microsoft Graph 请求 '/joinedTeams' 时出现“未经授权”错误

c# - 如何证明 Dictionary 的 TryGetValue 的双重检查锁定模式不是线程安全的

node.js - Azure,保持站点正常运行以执行常规批处理作业

azure - 将 azure-pipelines.yaml 迁移到单独的存储库,但在其他存储库的代码上运行

hadoop - MapReduce-生成HDFS路径

c# - 摘要泛型和摘要列表

c# - "Read .JSON file"统一 C# 中的方法,也适用于 IOS 和 Android 平台