最初にスキーマを抽出し、次にJavaのavroファイルからデータを抽出するにはどうすればよいですか? Javaを除いて this 質問と同じです。
Avscファイルからスキーマを取得する方法の例を見てきましたが、avroファイルからは取得しませんでした。どの方向でも大歓迎です。
Schema schema = new Schema.Parser().parse(new File("/home/Hadoop/Avro/schema/emp.avsc"));
対応するクラスを生成したり、ファイルが属するクラスを気にせずにAvroファイルのスキーマを知りたい場合は、GenericDatumReader
を使用できます。
DatumReader<GenericRecord> datumReader = new GenericDatumReader<>();
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<>(new File("file.avro"), datumReader);
Schema schema = dataFileReader.getSchema();
System.out.println(schema);
そして、ファイル内のデータを読み取ることができます。
GenericRecord record = null;
while (dataFileReader.hasNext()) {
record = dataFileReader.next(record);
System.out.println(record);
}
GenericDatumReader.getSchema()
を使用してスキーマを取得し、次にSchema.toString(true)
を使用して「きれいな」(インデントされた)文字列を取得します。
"getting started" doc と同じ例を使用:
DatumReader<User> userDatumReader = new SpecificDatumReader<>(User.class);
DataFileReader<User> dataFileReader = new DataFileReader<>(new File("users.avro"), userDatumReader);
// First, extract schema
Schema schema = dataFileReader.getSchema(); // <- get schema here
System.out.println(schema.toString(true)); // <- pretty-print here
// Then (if needed) read data
User user = null;
while (dataFileReader.hasNext()) {
// Reuse user object by passing it to next(). This saves us from allocating
// and garbage collecting many objects for files with many items.
user = dataFileReader.next(user);
System.out.println(user);
}
結果:
{
"type" : "record",
"name" : "User",
"namespace" : "example.avro",
"fields" : [ {
"name" : "name",
"type" : "string"
}, {
"name" : "favorite_number",
"type" : [ "int", "null" ]
}, {
"name" : "favorite_color",
"type" : [ "string", "null" ]
} ]
}
... followed with data.
ここに示すようにデータブリックライブラリを使用できます https://github.com/databricks/spark-avro これはavroファイルをDataframe
(_Dataset<Row>
_ )
_Dataset<Row>
_を取得したら、df.schema()
を使用してスキーマを直接取得できます。