标签:
先上图:
datafile(Avro标准序列生成二进制的文件)结构就如该图所示分为两块:
文件头
数据块(block)
public long getBlockCount()
:返回当前block数据块的对象个数public long getBlockSize()
:返回当前block数据块的大小public void seek(long position) throws IOException
:移动到参数指定的同步标记位置,该参数是由DataFileWriter.sync()
返回的
public void sync(long position) throws IOException
:移动到参数指定的位置的下一个同步标记位置。和上一个方法的区别是上一个方法必须知道明确的同步标记的位置,然后直接定位到该位置。而本方法是移动到给定的任意位置的下一个同步标记位。
public long previousSync()
:移动到当前位置的上一个同步标记位置。public long tell() throws IOException
:返回当前的位置public long sync() throws IOException
:生成一个同步标记位并写入当前数据块的同步标记为字段使得可以传递给DataFileReader.seek(long)
使用。同时强制到达本数据块的结尾(开启下一个数据块)
有些没搞清楚的就是当前的位置是如何给定的?有没有方法可以从一个位置跳转到另一个位置?同步标记为是随机生成?
添加对象到数据块前用tell()返回当前位置A,用appen()添加对象后在调用tell()返回的仍然是A。那么位置要经过什么情况才会变动??没有仔细研究所有API,暂时无法给出答案。
//User对象
File file = new File("users.avro");
DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
dataFileWriter.create(user1.getSchema(), new File("users.avro"));
dataFileWriter.append(user1);
dataFileWriter.append(user2);
dataFileWriter.append(user3);
dataFileWriter.close();
DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
DataFileReader<User> dataFileReader =
new DataFileReader<User>(file, userDatumReader);
User user = null;
while (dataFileReader.hasNext()) {
System.out.println(dataFileReader.getBlockSize());
// Reuse user object by passing it to next(). This saves us from
// allocating and garbage collecting many objects for files with
// many items.
user = dataFileReader.next(user);
System.out.println(user);
}
读取时可以使用dataFileReader
的sync(Long position)
和seek(Long position)
来读取指定的对象
标签:
原文地址:http://blog.csdn.net/blackcatdyx/article/details/51328918