转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9773233

所有源码在github上,https://github.com/lastsweetop/styhadoop

使用avro在很多情况下是对原有系统的改造,框架格式都已经定义好了,我们只能直接用avro对原有数据进行整合。(如果是新建系统,最好还是用avro的datafile,下一章讲datafile)

准备工作

将一下schema保存成文件StringPair.avsc,放在src/test/resources目录下
{
"type":"record",
"name":"StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"left","type":"string"},
{"name":"right","type":"string"}
]
}
引入最新版本的avro时要主要,最新的avro包为1.7.4,依赖org.codehaus.jackson:jackson-core-asl:1.8.8包,但是maven库中已经没有该版本
所以要换成其他版本
    <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.9</version>
</dependency>

如果你用的时1.0.4版本的hadoop(或者其他版本),依赖于jackson-mapper-asl,如果与jackson-core-asl版本不一致就会产生找不到方法等异常

你需要入引入相同版本
            <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>

generic方式

这一节我们用代码讲解
package com.sweetop.styhadoop;

import junit.framework.Assert;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.*;
import org.junit.Test; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; /**
* Created with IntelliJ IDEA.
* User: lastsweetop
* Date: 13-8-5
* Time: 下午7:59
* To change this template use File | Settings | File Templates.
*/
public class TestGenericMapping {
@Test
public void test() throws IOException {
//将schema从StringPair.avsc文件中加载
Schema.Parser parser = new Schema.Parser();
Schema schema = parser.parse(getClass().getResourceAsStream("/StringPair.avsc")); //根据schema创建一个record示例
GenericRecord datum = new GenericData.Record(schema);
datum.put("left", "L");
datum.put("right", "R"); ByteArrayOutputStream out = new ByteArrayOutputStream();
//DatumWriter可以将GenericRecord变成edncoder可以理解的类型
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
//encoder可以将数据写入流中,binaryEncoder第二个参数是重用的encoder,这里不重用,所用传空
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writer.write(datum,encoder);
encoder.flush();
out.close(); DatumReader<GenericRecord> reader=new GenericDatumReader<GenericRecord>(schema);
Decoder decoder=DecoderFactory.get().binaryDecoder(out.toByteArray(),null);
GenericRecord result=reader.read(null,decoder);
Assert.assertEquals("L",result.get("left").toString());
Assert.assertEquals("R",result.get("right").toString());
}
}

result.get返回的是utf-8格式,需要调用toString方法,才能和字符串一致。

specific方式

首先使用avro-maven-plugin生成代码,pom的配置
  <plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.0</version>
<executions>
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<includes>
<include>StringPair.avsc</include>
</includes>
<sourceDirectory>src/test/resources</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

avro-maven-plugin插件绑定在generate-sources阶段,调用mvn generate-sources即可生成源代码,我们来看下生成的源代码

package com.sweetop.styhadoop;

/**
* Autogenerated by Avro
* <p/>
* DO NOT EDIT DIRECTLY
*/
@SuppressWarnings("all")
/** A pair of strings */
public class StringPair extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"StringPair\",\"doc\":\"A pair of strings\",\"fields\":[{\"name\":\"left\",\"type\":\"string\",\"avro.java.string\":\"String\"},{\"name\":\"right\",\"type\":\"string\"}]}");
@Deprecated
public java.lang.CharSequence left;
@Deprecated
public java.lang.CharSequence right; public org.apache.avro.Schema getSchema() {
return SCHEMA$;
} // Used by DatumWriter. Applications should not call.
public java.lang.Object get(int field$) {
switch (field$) {
case 0:
return left;
case 1:
return right;
default:
throw new org.apache.avro.AvroRuntimeException("Bad index");
}
} // Used by DatumReader. Applications should not call.
@SuppressWarnings(value = "unchecked")
public void put(int field$, java.lang.Object value$) {
switch (field$) {
case 0:
left = (java.lang.CharSequence) value$;
break;
case 1:
right = (java.lang.CharSequence) value$;
break;
default:
throw new org.apache.avro.AvroRuntimeException("Bad index");
}
} /**
* Gets the value of the 'left' field.
*/
public java.lang.CharSequence getLeft() {
return left;
} /**
* Sets the value of the 'left' field.
*
* @param value the value to set.
*/
public void setLeft(java.lang.CharSequence value) {
this.left = value;
} /**
* Gets the value of the 'right' field.
*/
public java.lang.CharSequence getRight() {
return right;
} /**
* Sets the value of the 'right' field.
*
* @param value the value to set.
*/
public void setRight(java.lang.CharSequence value) {
this.right = value;
}
}

为了兼容之前的版本生成了一组get,put方法,1.6.0后生成添加了getter/setter方法,还有一个与Builder的类,没什么用已经被我删掉

另外上一篇文章有点没讲到就是schama里的name里可以使用命名空间,如com.sweetop.styhadoop.StringPair,这样生成的源代码才会是带package的

那我们来看如果使用这个生成的类,和generic方式有什么不同:

package com.sweetop.styhadoop;

import junit.framework.Assert;
import org.apache.avro.Schema;
import org.apache.avro.io.*;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.junit.Test; import java.io.ByteArrayOutputStream;
import java.io.IOException; /**
* Created with IntelliJ IDEA.
* User: lastsweetop
* Date: 13-8-6
* Time: 下午2:19
* To change this template use File | Settings | File Templates.
*/
public class TestSprecificMapping {
@Test
public void test() throws IOException {
//因为已经生成StringPair的源代码,所以不再使用schema了,直接调用setter和getter即可
StringPair datum=new StringPair();
datum.setLeft("L");
datum.setRight("R"); ByteArrayOutputStream out=new ByteArrayOutputStream();
//不再需要传schema了,直接用StringPair作为范型和参数,
DatumWriter<StringPair> writer=new SpecificDatumWriter<StringPair>(StringPair.class);
Encoder encoder= EncoderFactory.get().binaryEncoder(out,null);
writer.write(datum, encoder);
encoder.flush();
out.close(); DatumReader<StringPair> reader=new SpecificDatumReader<StringPair>(StringPair.class);
Decoder decoder= DecoderFactory.get().binaryDecoder(out.toByteArray(),null);
StringPair result=reader.read(null,decoder);
Assert.assertEquals("L",result.getLeft().toString());
Assert.assertEquals("R",result.getRight().toString());
}
}

不同点总结一下, schema->StringPair.class,      GenericRecord->StringPair

hadoop深入研究:(十六)——Avro序列化与反序列化的更多相关文章

  1. hadoop深入研究:(十八)——Avro schema兼容

    转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9900129 所有源码在github上,https://github.com/l ...

  2. Avro序列化与反序列化

    4.Avro实现序列化的步骤 1.创建maven工程,引入pom文件(定义属性和依赖信息,以及定义Avro插件) 2.根据Avro插件的要求,更改maven工程结构,需要创建一个source/main ...

  3. Hadoop基础-序列化与反序列化(实现Writable接口)

    Hadoop基础-序列化与反序列化(实现Writable接口) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.序列化简介 1>.什么是序列化 序列化也称串行化,是将结构化 ...

  4. go语言之行--文件操作、命令行参数、序列化与反序列化详解

    一.简介 文件操作对于我们来说也是非常常用的,在python中使用open函数来对文件进行操作,而在go语言中我们使用os.File对文件进行操作. 二.终端读写 操作终端句柄常量 os.Stdin: ...

  5. Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

    酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...

  6. hadoop深入研究:(十三)——序列化框架

    hadoop深入研究:(十三)--序列化框架 Mapreduce之序列化框架(转自http://blog.csdn.net/lastsweetop/article/details/9376495) 框 ...

  7. 第十六篇 .NET高级技术之序列化

    .net framework的类库中提供了三个可以用于序列化和反序列化的类,分别为BinaryFormatter.SoapFormatter和XmlSerializer. BinaryFormatte ...

  8. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  9. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

随机推荐

  1. IEEE论文格式要求

    0.特别提示:本次会议要求各位作者根据审稿意见进行认真修改,然后经过大会主席的检查合格才允许上传IEEE eXpress,主要的目的是为了保证论文集的质量,不让论文格式出现五花八门的情况,确保会议后被 ...

  2. [Cycle.js] Fine-grained control over the DOM Source

    Currently in our main() function,  we get click$ event. function main(sources) { const click$ = sour ...

  3. LoadRunner监控windows资源报错Monitor name :Windows Resources. Cannot connect to machine

    目标机:被监控的机器,windows server 2008 R2. 测试机:执行control的机器,windows7 操作:在测试机上执行Control,添加windows的监控 问题现象:Mon ...

  4. (转载)Linux网络配置和setup工具包安装

    查看网卡是否正常安装 命令:lspci |grep Ether 1.修改网卡配置 命令: vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth ...

  5. iOS_SN_详解沙河(转载)

    一 查看沙盒结构 和一些百度来的博客显示隐藏稳文件的方式不同,本文也提供两种方式,简单粗暴. 方式一 使用工具simpholders(推荐) 下载链接 http://simpholders.com/  ...

  6. OpenGL ES 2.0 雾

    在场景中使用雾不但可以提高真实感,特定的情况下还能优化性能.具体是指当物体离摄像机足够远时,雾就足够浓,此时只能看到雾而看不到物体,也就不必对物体着色进行详细计算,这样可以大大提高渲染效率. 雾有很多 ...

  7. unique &unique_copy

      unique (ForwardIterator first, ForwardIterator last); unique (ForwardIterator first, ForwardIterat ...

  8. Gruntjs构工具学习视频

    在这里推荐一个Gruntjs的学习视频,非常不错! http://www.imooc.com/learn/30

  9. 02—从Cocos2DX视角看游戏组成

    Cocos2DX引擎按照层次逻辑将游戏元素细分为:导演CCDirector.场景CCScene.图层CCLayer.精灵CCSprite.在上面篇中我们已经知道除导演CCDirector外都继承了CC ...

  10. windows下使用php重命名目录下的文件

    rename函数一直报错,最后发现是windows下文件名的编码问题,如果项目文件是utf-8的话,一定要经过一步转码 $dir = $path . '/../resource/logo'; $han ...