现在的位置: 首页 > 综合 > 正文

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

2013年08月03日 ⁄ 综合 ⁄ 共 1824字 ⁄ 字号 评论关闭

转载请写明来源地址: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文件

void	seek(long position)
Move to a specific, known synchronization point, one returned from DataFileWriter.sync() while writing.
void	sync(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"));
        }

【上篇】
【下篇】

抱歉!评论已关闭.