原文地址: itweknow.cn/detail?id=7… ,歡迎你們訪問。java
Avro是一個獨立於編程語言的數據序列化系統。這個項目由Ddoug Cutting(Hadoop之父)建立,目標是解決Hadoop中Writable類型缺少語言的可移植性的不足。Avro模式一般採用JSON來寫,數據則採用二進制格式編碼,也可採用基於JSON的數據編碼方式。編程
Avro定義了一些基本的數據類型,咱們能夠用他們來構建應用特定的數據結構。下面的表格咱們列舉了Avro的基本類型。json
類型 | 描述 | 模式示例 |
---|---|---|
null | 空值 | "null" |
boolean | 二進制值 | "boolean" |
int | 32位帶符號整數 | "int" |
long | 64位帶符號整數 | "long" |
float | 單精度(32位)浮點數 | "float" |
double | 雙精度(64位)浮點數 | "double" |
bytes | 8位無符號字節序列 | "bytes" |
string | Unicode字符序列 | "string" |
還有一些複雜的類型以下表所示:數組
類型 | 描述 | 模式示例 |
---|---|---|
array | 一個排過序的對象集合。特定數組中的全部對象必須模式相同。 | {"type": "array","items": "long"} |
map | 未排過序的鍵-值對。鍵必須是字符串,值能夠是任何一種類型,可是某一個map內的全部值必須模式相同。 | {"type": "map", "values": "string"} |
record | 一個任意類型的命名字段集合。(至關於java中的自定義對象) | {"type": "record", "name": "User", "doc":"A User Desc","fileds":[{"name":"nickname","type": "string"},{"name":"age","type":"int"}]} |
enum | 一個命名的值集合(枚舉) | {"type":"enum","name":"ActionStatus","doc":"操做狀態","symbols":["SUCCESS","FAILED","ACTING"]} |
fixed | 一組固定數量的8位無符號字節 | {"type":"fixed","name":"Md5Hash","size":16} |
union | 模式的並集。並集可用JSON數組表示,其中每一個元素爲一個模式。並集表示的數據必須與其內的某個模式相匹配 | ["null","string",{"type":"map","values":"string"}] |
前面也提到過設計Avro的目的就是解決Hadoop中Writable類型缺少語言的可移植性的不足。Avro數據文件主要是面向跨語言使用而設計的,咱們能夠經過Java寫入文件,而後經過Python來讀取文件,這都是沒有問題的。數據文件的頭部包含一個Avro模式和一個同步標識(sync marker),而後緊接着是一系列包含序列化Avro對象的數據塊。數據塊經過sync marker分隔。 這裏有兩個概念解釋一下:數據結構
上面也簡單的瞭解了一下Avro,下面咱們經過兩段代碼來嘗試一下Avro的序列化和反序列化。app
{
"type": "record",
"name": "User",
"doc": "一個用戶",
"fields": [
{"name": "name", "type": "string"},
{"name": "age", "type": "int"}
]
}
複製代碼
@Test
public void write() throws IOException {
Schema.Parser parser = new Schema.Parser();
InputStream in = this.getClass().getResourceAsStream("User.avsc");
Schema schema = parser.parse(in);
GenericRecord record = new GenericData.Record(schema);
record.put("name", "ganchaoyang");
record.put("age", 23);
File file = new File("result.avro");
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
try(DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(writer)) {
dataFileWriter.create(schema, file);
dataFileWriter.append(record);
}
}
複製代碼
@Test
public void read() throws IOException {
File file = new File("result.avro");
DatumReader<GenericRecord> reader = new GenericDatumReader<>();
try (DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, reader)) {
GenericRecord record;
while (dataFileReader.hasNext()) {
record = dataFileReader.next();
Assert.assertEquals("ganchaoyang", record.get("name").toString());
Assert.assertEquals(23, record.get("age"));
}
}
}
複製代碼