avro序列化详细操作

Intellij 15.0.3

Maven

avro 1.8.0

Avro是一个数据序列化系统。

它提供以下:

1 丰富的数据结构类型

2 快速可压缩的二进制数据形式

3 存储持久数据的文件容器

4 远程过程调用RPC

5 简单的动态语言结合功能,Avro和动态语言结合后,读写数据文件和使用RPC协议都不需要生成代码,而代码生成作为一种可选的优化只值得在静态类型语言中实现。

Avro依赖于模式(Schema)。Avro数据的读写操作是很频繁的,而这些操作都需要使用模式,这样就减少写入每个数据资料的开销,使得序列化快速而又轻巧。这种数据及其模式的自我描述方便于动态脚本语言的使用。

下面介绍如果使用avro进行序列化和反序列化的操作

前置条件:

maven项目

1、在pom.xml中添加avro的依赖包和编译插件

1.1 配置avro依赖

在dependencies中配置avro的GAV

<dependency>
    <groupId>org.apache.avro</groupId>
    <artifactId>avro</artifactId>
    <version>1.8.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

1.2 在build–>plugins下配置编译插件

<plugin>
    <groupId>org.apache.avro</groupId>
    <artifactId>avro-maven-plugin</artifactId>
    <version>1.8.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>schema</goal>
            </goals>
            <configuration>
                <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
                <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2、定义avro的scheme

Avro scheme是通过JSON形式来定义的,一般以.avsc结尾(maven插件会去指定目录下获取.avsc结尾的文件并生成成Java文件)

2.1 在src/main目录下新建一个avro文件夹

2.2 在src/main/avro目录下新建一个文件,并保存为user.avsc。文件内容如下:

{"namespace": "cn.md31.avro.test.bean",
 "type": "record",
 "name": "User",
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number",  "type": ["int", "null"]},
     {"name": "favorite_color", "type": ["string", "null"]}
 ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

其中

namespace在java项目中翻译成包名

name是类名

fields就是配置的属性

注意:必须配置type为record

2.3 生成User的java文件

avro提供了一个avro-tools包来生成java文件,可以通过下面命令:

java -jar /path/to/avro-tools-1.8.0.jar compile schema <schema file> <destination>
  • 1
  • 1

在1.2步中,pom文件中配置了插件,所以在maven项目中,我们只需要执行mvn complie 命令就可以自动生成java文件了。

注:插件会自动搜索src/main/avro目录下的.avsc结尾的文件,并生成java文件到src/main/java包下

因为我们在pom文件中指定了相应目录:

如果使用Intellij,我们直接执行compile即可:

执行之后会在相应目录生成User.java文件

1 使用生成的User类初始化User对象

Avro自动生成的User类有三种方式初始化:

1.1 使用构造方法:

User user1 = new User("user1", 10, "red");

1.2 使用setter方法

User user2 = new User();
user2.setName("user2");
user2.setFavoriteNumber(11);
user2.setFavoriteColor("white");
  • 1
  • 2

1.3 使用build方法

User user3 = User.newBuilder()
        .setName("user3")
        .setFavoriteNumber(12)
        .setFavoriteColor("black")
        .build();

整合到produceUsers方法中:

public static List<User> produceUsers() {
    List<User> userList = new ArrayList<User>();
    // 三种初始化方式
    User user1 = new User("user1", 10, "red");
    User user2 = new User();
    user2.setName("user2");
    user2.setFavoriteNumber(11);
    user2.setFavoriteColor("white");
    User user3 = User.newBuilder()
            .setName("user3")
            .setFavoriteNumber(12)
            .setFavoriteColor("black")
            .build();
    userList.add(user1);
    userList.add(user2);
    userList.add(user3);
    return userList;
}

2 把User对象序列化到文件中

public static void serializeAvroToFile(List<User> userList, String fileName) throws IOException {
    DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
    DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
    dataFileWriter.create(userList.get(0).getSchema(), new File(fileName));
    for (User user: userList) {
        dataFileWriter.append(user);
    }
    dataFileWriter.close();
}

在main方法中调用上面两个方法

public static void main(String[] args) throws IOException {
    List<User> userList = produceUsers();
    String fileName = "users.avro";
    serializeAvroToFile(userList, fileName);
//        deserializeAvroFromFile(fileName);
//
//        byte[] usersByteArray = serializeAvroToByteArray(userList);
//        deserialzeAvroFromByteArray(usersByteArray);
}

执行main方法,会发现在根目录生成了一个users.avro文件:

3 从文件中反序列化对象

public static void deserializeAvroFromFile(String fileName) throws IOException {
    File file = new File(fileName);
    DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
    DataFileReader<User> dataFileReader = new DataFileReader<User>(file, userDatumReader);
    User user = null;
    System.out.println("----------------deserializeAvroFromFile-------------------");
    while (dataFileReader.hasNext()) {
        user = dataFileReader.next(user);
        System.out.println(user);
    }
}

执行之后得到结果:

4、序列化对象成byte 数组

public static byte[] serializeAvroToByteArray(List<User> userList) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
        DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
        dataFileWriter.create(userList.get(0).getSchema(), baos);
        for (User user: userList) {
            dataFileWriter.append(user);
        }
        dataFileWriter.close();
        return baos.toByteArray();
    }

5、从byte数组中反序列化成对象

public static void deserialzeAvroFromByteArray(byte[] usersByteArray) throws IOException {
        SeekableByteArrayInput sbai = new SeekableByteArrayInput(usersByteArray);
        DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
        DataFileReader<User> dataFileReader = new DataFileReader<User>(sbai, userDatumReader);
        System.out.println("----------------deserialzeAvroFromByteArray-------------------");
        User readUser = null;
        while (dataFileReader.hasNext()) {
            readUser = dataFileReader.next(readUser);
            System.out.println(readUser);
        }
    }
时间: 2024-08-25 15:31:39

avro序列化详细操作的相关文章

(47) odoo详细操作手册

odoo 8 详细操作手册, ERP(Odoo8.0)操作手册-v1.10(陈伟明).pdf 链接: http://pan.baidu.com/s/1hsp0bVQ 密码: r9tt 花了将近9个月时间平时整理的手册,共913页,可能稍微有点长,但还是很有参考价值, 希望对大家有帮助.

iOS数据库操作之coredata详细操作步骤

CHENYILONG Blog iOS数据库操作之coredata详细操作步骤 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong iOS应用数据存取的常用方式 ? XML属性列表 -- PList? NSKeyedArchiver 归档 ?Preference(偏好设置) ? SQLite3? Core DataCore Data简介 ? Core Data 是iOS SDK 里的一个很强大的

ASP.NET三层架构基础详细操作图文教程(转)

本文主要讲述Asp.net B/S结构 下基础的三层架构项目.三层主要是指的界面UI层,逻辑层,数据层.界面UI层:用于用户观看,体验的表示层.逻辑层:程序运行逻辑的封装层.数据层:程序数据相关操作的封装层. 每层当中还可以进行不同的详细划分,因为是基础教程,先领新手入门,所以不进行复杂的讲解.本来出自http://www.cnntec.com 作者:A.Z猫 转载请注明,违者必究.准备工具:Microsoft Visual Studio 2008 以下简称vs08Microsoft SQLSe

JQuery 对表格的详细操作

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><ht

Nginx反向绑定域名方法和详细操作应用实例:Google和Gravatar

反向绑定域名,即将域名B绑定到域名A上,用户只要访问B就等同于进入A,内容都是由A提供,它有点像建立了一个A的镜像.什么时候要用到反向绑定域名?服务器集群和网站负载均衡时,把用户访问请求发送不同的服务器上. 关于反向绑定域名的方法部落之前也分享过好几次,本篇文章就来详细介绍一下Nginx反向绑定域名方法.之所以要用Nginx,主要在于Nginx在反向绑定域名有着天然的优势,并且功能强大,可以满足我们更多更高的应用需求. 平常我们都是用Nginx反向绑定域名来搞定无法绑定域名的空间,这次来分享一下

Django 框架篇(五): ORM详细操作

 ORM之models.py  字段: 常用字段 : AutoField: 自增的整形字段,必填参数primary_key=True,则成为数据库的主键.无该字段时,django自动创建. 一个model不能有两个AutoField字段. IntegerField: 一个整数类型.数值的范围是 -2147483648 ~ 2147483647. CharField: 字符类型,必须提供max_length参数.max_length表示字符的长度. DateField: 日期类型,日期格式为YYY

科研及工程实践中光纤涂覆机详细操作步骤(图文)

科研及工程实践中光纤涂覆机详细操作步骤(图文)一.清洁涂覆夹具涂覆夹具包括上.下两片光滑的石英片,每片的中间有一个半圆形槽,为了使上下两石英片扣和形成完美的圆形腔,需要清洁附着在石英片表面的灰尘,可以使用无尘纸沾酒精来清洗.用沾有酒精的无尘纸轻轻擦拭石英片,擦拭时候注意从一边单向擦拭,切勿来回擦拭(来回擦拭擦不干净,同时容易损伤石英表面镀金层),擦拭完毕后稍等残余酒精挥发或者用干的无尘纸再擦拭一遍后进行下一步操作.请注意:清洗时需轻轻擦拭,以防划伤石英片光滑表面 二.连接电源三.打开涂覆机电源开

Windows server iis部署Django详细操作

教程基于Windows server2012+Python3.6+IIS之上部署django的,同样适用于server2012之上的版本服务器和windows7以上的windows操作系统. 文章来自:django中文网,https://www.django.cn/article/show-21.html 如果觉得看文字没意思,想看视频教程的,请点击这里:Django项目部署视频教程 1.安装IIS和CGI 打开服务器管理器,选择添加角色和功能,选择要添加的服务器角色(WEB服务器IIS),然后

表详细操作

表的详细操作: 1.修改表名: alter table 旧表名 rename 新表名 2.修改表的引擎与字符编码: alter table 表名 engine ='引擎名' charset='编码名'; 3.复制表 create table 新表名 like 旧表名; create table 新表名 select * from 表名 where 条件; 4.清空表: truncate 表名: 表被清空,包括自增字段 表中字段的详细操作: 1.需要改字段信息: alter table 表名 mo