hadoop深入研究:(十七)——Avro Datafile

来源:互联网 发布:网络资源管理系统 编辑:程序博客网 时间:2024/06/07 23:20

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

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

datafile组成

datafile的组成如下图:

datafile分为文件头是数据块,如果看图还是不明白,那么看这个应该会很清楚,datafile文件头的schema:
{"type": "record", "name": "org.apache.avro.file.Header", "fields" : [   {"name": "magic", "type": {"type": "fixed", "name": "Magic", "size": 4}},   {"name": "meta", "type": {"type": "map", "values": "bytes"}},   {"name": "sync", "type": {"type": "fixed", "name": "Sync", "size": 16}},  ]}
数据块相对容易理解,这里就不详述了。
要注意的是16字节的同步标记,这个标记意味着datafile支持随机读,并且可以做分割,也意味着可以作为mapreduce的输入

DataFileReader可以通过同步标记去随机读datafile文件

voidseek(long position)Move to a specific, known synchronization point, one returned from DataFileWriter.sync() while writing.voidsync(long position)Move to the next synchronization point after a position.

datafile写操作

以代码注释的方式进行讲解:
//首先创建一个扩展名为avro的文件(扩展名随意,这里只是为了容易分辨)        File file = new File("data.avro");        //这行和前篇文章的代码一致,创建一个Generic Record的datum写入类        DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);        //和Encoder不同,DataFileWriter可以将avro数据写入到文件中        DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(writer);        //创建文件,并且写入头信息        dataFileWriter.create(schema,file);        //写datum数据        dataFileWriter.append(datum);        dataFileWriter.append(datum);        dataFileWriter.close();

datafile读操作

以代码注释的方式进行讲解

//这行也和前篇文章相同,Generic Record的datum读取类,有点不一样的就是这里不需要再传入schema,因为schema已经包含在datafile的头信息里        DatumReader<GenericRecord> reader=new GenericDatumReader<GenericRecord>();        //datafile文件的读取类,指定文件和datumreader        DataFileReader<GenericRecord> dataFileReader=new DataFileReader<GenericRecord>(file,reader);        //测试下读写的schema是否一致        Assert.assertEquals(schema,dataFileReader.getSchema());        //遍历GenericRecord        for (GenericRecord record : dataFileReader){            System.out.println("left="+record.get("left")+",right="+record.get("right"));        }