如何在Java或Scala中读取和写入Map<String,Object>来自/到镶木地板文件?

2022-09-04 04:52:32

寻找一个关于如何在Java或Scala中读取和写入镶木地板文件的简洁示例?Map<String, Object>

这是预期的结构,在Java中用作序列化程序(即使用镶木地板寻找等效项):com.fasterxml.jackson.databind.ObjectMapper

public static Map<String, Object> read(InputStream inputStream) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();

    return objectMapper.readValue(inputStream, new TypeReference<Map<String, Object>>() {

    });
}

public static void write(OutputStream outputStream, Map<String, Object> map) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();

    objectMapper.writeValue(outputStream, map);        
}

答案 1

我对镶木地板不是很了解,但是,从这里开始

Schema schema = new Schema.Parser().parse(Resources.getResource("map.avsc").openStream());

    File tmp = File.createTempFile(getClass().getSimpleName(), ".tmp");
    tmp.deleteOnExit();
    tmp.delete();
    Path file = new Path(tmp.getPath());

    AvroParquetWriter<GenericRecord> writer = 
        new AvroParquetWriter<GenericRecord>(file, schema);

    // Write a record with an empty map.
    ImmutableMap emptyMap = new ImmutableMap.Builder<String, Integer>().build();
    GenericData.Record record = new GenericRecordBuilder(schema)
        .set("mymap", emptyMap).build();
    writer.write(record);
    writer.close();

    AvroParquetReader<GenericRecord> reader = new AvroParquetReader<GenericRecord>(file);
    GenericRecord nextRecord = reader.read();

    assertNotNull(nextRecord);
    assertEquals(emptyMap, nextRecord.get("mymap"));

在您的情况下,更改(Google收藏夹)的默认地图如下:ImmutableMap

Schema schema = new Schema.Parser().parse( Resources.getResource( "map.avsc" ).openStream() );

        File tmp = File.createTempFile( getClass().getSimpleName(), ".tmp" );
        tmp.deleteOnExit();
        tmp.delete();
        Path file = new Path( tmp.getPath() );

        AvroParquetWriter<GenericRecord> writer = new AvroParquetWriter<GenericRecord>( file, schema );

        // Write a record with an empty map.
        Map<String,Object> emptyMap = new HashMap<String, Object>();

        // not empty any more
        emptyMap.put( "SOMETHING", new SOMETHING() );
        GenericData.Record record = new GenericRecordBuilder( schema ).set( "mymap", emptyMap ).build();
        writer.write( record );
        writer.close();

        AvroParquetReader<GenericRecord> reader = new AvroParquetReader<GenericRecord>( file );
        GenericRecord nextRecord = reader.read();

        assertNotNull( nextRecord );
        assertEquals( emptyMap, nextRecord.get( "mymap" ) );

我没有测试代码,但试了一下。


答案 2

我怀疑是否有现成的解决办法。当您谈论Maps时,如果Maps的值是基元类型,或者是turn具有基元类型字段的complexType,则仍然可以从中创建AvroSchema。

在您的情况下,

  • 如果您有一个 Map => 它将创建 map 值为 int 的架构。
  • 如果您有地图,
    • 一个。自定义对象具有字段 int、float、char ...(即任何基元类型)模式生成将是有效的,然后可用于成功转换为镶木地板。
    • b.自定义对象具有非基元字段,生成的架构将格式不正确,并且生成的 ParquetWritter 将失败。

要解决此问题,您可以尝试将对象转换为 ,然后使用 Apache Spark 库将其转换为 Parquet。JsonObject


推荐