【问题标题】:Converting Avro Binary String to Json将 Avro 二进制字符串转换为 Json
【发布时间】:2019-10-14 07:18:18
【问题描述】:

我有一个 Avro 二进制格式的字符串。我想将字符串转换为 json。有人可以指导我吗?我尝试使用在线提供的解决方案它不起作用。

public String avroToJson(byte[] avro) throws IOException {
        boolean pretty = false;
        GenericDatumReader<GenericRecord> reader = null;
        JsonEncoder encoder = null;
        ByteArrayOutputStream output = null;
        try {
            reader = new GenericDatumReader<GenericRecord>();
            InputStream input = new ByteArrayInputStream(avro);
            DataFileStream<GenericRecord> streamReader = new DataFileStream<GenericRecord>(input, reader);
            output = new ByteArrayOutputStream();
            Schema schema = streamReader.getSchema();
            DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
            encoder = EncoderFactory.get().jsonEncoder(schema, output, pretty);
            for (GenericRecord datum : streamReader) {
                writer.write(datum, encoder);
            }
            encoder.flush();
            output.flush();
            return new String(output.toByteArray());
        } finally {
            try {
                if (output != null) output.close();
            } catch (Exception e) {
            }
        }
    }

我正在使用 getBytes() 将我的字符串转换为字节数组并将其传递给此函数。我得到了这个例外。 线程“主”org.apache.avro.InvalidAvroMagicException 中的异常:不是 Avro 数据文件。

【问题讨论】:

标签: java avro


【解决方案1】:

Avro 为序列化一个对象指定了一种二进制格式,但也指定了一个Object Container File(也称为数据文件),它可以以一种有用的方式保存许多对象以进行文件访问。

DataFileStream 需要容器文件,但根据您的描述,您似乎只有一个序列化实例。

你可能想要这样的东西:

  public String avroToJson(Schema schema, byte[] avroBinary) throws IOException {
    // byte to datum
    DatumReader<Object> datumReader = new GenericDatumReader<>(schema);
    Decoder decoder = DecoderFactory.get().binaryDecoder(avroBinary, null);
    Object avroDatum = datumReader.read(null, decoder);

    // datum to json
    String json = null;
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
      DatumWriter<Object> writer = new GenericDatumWriter<>(schema);
      JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, baos, false);
      writer.write(avroDatum, encoder);
      encoder.flush();
      baos.flush();
      return new String(baos.toByteArray(), StandardCharsets.UTF_8);
    }
  }

请注意,这意味着您必须提前知道架构才能反序列化二进制数据。如果它一个 Avro 数据文件,您可以从文件元数据中获取架构。

【讨论】:

    猜你喜欢
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2019-08-23
    • 1970-01-01
    相关资源
    最近更新 更多