Преобразование двоичной строки Avro в Json - PullRequest
0 голосов
/ 14 октября 2019

У меня есть строка в двоичном формате 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) {
            }
        }
    }

Я конвертирую массив String в байтовый массив с помощью getBytes () и передаю его этой функции. Я получаю это исключение. Исключение в потоке "main" org.apache.avro.InvalidAvroMagicException: не файл данных Avro.

1 Ответ

0 голосов
/ 15 октября 2019

Avro указывает двоичный формат для сериализации одного объекта, но также и файл контейнера объектов (также известный как файл данных), который может содержать множество объектов полезным способом для доступа к файлу.

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, вы могли бы получить схему из метаданных файла.

...