5.4.1 sequenceFile读写文件、记录边界、同步点、压缩排序、格式
5.4.1 sequenceFile读写文件、记录边界、同步点、压缩排序、格式
HDFS和MapReduce是针对大文件优化的存储文本记录,不适合二进制类型的数据。SequenceFile作为小文件的容器,SequenceFile类型将小文件包装起来,可以获得更高效率的存储和处理。sequenceFile类非常适合日志形式的存储方式,将日志记录按照【key,value】(key对应行号,valuse内容,key和value不一定需要writable类型,可以任意可序列化的类型)对格式存储,sequenceFile可以高效存储小文件。
(1)写入数据到文件
通过createWriter创建写入对象writer,通过writer的append函数追加到文件末尾,写完后调用close关闭。
public class SequenceFileWriteDemo {
private static final String[] DATA = { "One, two, buckle my shoe",
"Three, four, shut the door", "Five, six, pick up sticks",
"Seven, eight, lay them straight", "Nine, ten, a big fat hen" };
public static void main(String[] args) throws IOException {
String uri = args[0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
IntWritable key = new IntWritable();
Text value = new Text();
SequenceFile.Writer writer = null;
try {
//根据文件系统,配置,路径,键值的类名创建writer
writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass());
for (int i = 0; i < 100; i++) {
key.set(100 - i);
value.set(DATA[i % DATA.length]);
System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key,
value);
//append追加数据
writer.append(key, value);
}
} finally {
//关闭数据流
IOUtils.closeStream(writer);
}
}
}
(2)从文件读取数据
通过SequenceFile.Reader reader =SequenceFile.Reader(fs, path, conf);函数返回reader对象,然后通过reader.next(key,value)去遍历获取数据,末尾返回false;
public class SequenceFileReadDemo {
public static void main(String[] args) throws IOException {
String uri = args[0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
SequenceFile.Reader reader = null;
try {
reader = new SequenceFile.Reader(fs, path, conf);
Writable key = (Writable) ReflectionUtils.newInstance(
reader.getKeyClass(), conf);
Writable value = (Writable) ReflectionUtils.newInstance(
reader.getValueClass(), conf);
long position = reader.getPosition();
while (reader.next(key, value)) {
String syncSeen = reader.syncSeen() ? "*" : "";
System.out.printf("[%s%s]\t%s\t%s\n", position, syncSeen, key,
value);
position = reader.getPosition(); // beginning of next record
}
} finally {
IOUtils.closeStream(reader);
}
}
}
(3)其他序列化框架调用方法
对于其他非Writable类型的序列化框架(比如Apache Thrift),则应该使用下面两个方法:
public Object next(Object key) throws IOException
public Object getCurrentValue(Object val) throws IIOException
在这种情况下,需要确保io.serializations属性已经设置了你想使用的序列化框架。如果next()方法返回的是非null对象,则可以从数据流中读取键、值对,并且可以通过getCurrentValue()方法读取该值。否则,如果next()返回null值,则表示已经读到文件末尾。
(4)记录边界和同步点
记录边界:是每条记录和前后记录交界的地方,是一记录开始或结束的地方。使用reader.next()获取记录时需要从记录边界开始读取,否则会出现IOException。
同步点:同步点是由SequenceFile.Writer记录的,在顺序文件写入过程中插入一个特殊项以便每隔几个记录便有一个同步标识。同步点会占用很小的存储空间。同步点是为了方便读取数据而设立的,读取数据时,由于搜索而跑到任意位置,非记录边界读取会引起异常,这时就需要通过同步点找下一个记录边界。
通过同步点查找记录边界。SequenceFile.Reader记录sync(long position)方法可以将读取位置定位到position之后的下一个同步点。如果position之后没有同步了,那么当前读取位置将指向文件末尾。这样,我们对数据流中的任意位置调用sync()方法(不一定是一个记录的边界)而且可以重新定位到下一个同步点并继续向后读取:
reader.sync(360);
assertThat(reader.getPosition(), is(2021L));
assertThat(reader.next(key, value), is(true));
assertThat(((IntWritable) key).get(), is(59));
SequenceFile.Writer对象有一个Sync()方法,该方法可以在数据流的当前位置插入一个同步点。
另外一种搜索记录边界的方法是调用seek(int position)方法,但是只能知道提前知道记录边界的指定位置。该方法将读指针指向文件中指定的position位置。例如,可以按如下方式搜查记录边界:
reader.seek(359);
assertThat(reader.next(key, value), is(true));
assertThat(((IntWritable) key).get(), is(95));
但如果给定位置不是记录边界,调用next()方法时就会出错:
reader.seek(360);
reader.next(key, value); // fails with IOException
(5)查看序列化文件
可以用hadoop fs –text number.seq | head查看文件的文本。可以识别gzip压缩文件,顺序文件和Avro数据文件。
(6)输出排序后的sequenceFile文件
Hadoop执行mapreduce任务时,指定sort -r进行排序,inFormat指定指定输入文件类型,outFormat指定输出文件类型,outKey指定输出键类型,outValue指定输出值类型,最后加上出入文件和输出文件路径,执行完任务后,在输出文件夹sorted中有生成的输出文件,是排好序的。
(7)sequenceFile文件格式
SequenceFile文件内容由文件头hearder(SEQ、版本、键和值类的名称、数据压缩细节、用户定义的元数据),记录,同步标识组成。
记录的内部结构取决于是否启用压缩。压缩方式有记录压缩和数据块压缩。记录压缩是单挑记录值进行压缩,数据块压缩是一次性对多条记录压缩,可以不断向数据块中压缩记录,直到块的字节数不小于io.seqfile.compress.blocksize属性中设置的字节数:默认为1MB。每一个新块的开始处都需要插入同步标识。

记录压缩

数据块压缩
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
5.4.1 sequenceFile读写文件、记录边界、同步点、压缩排序、格式的更多相关文章
- Inno Setup 如何读写文件
软件安装的实质就是拷贝,对于简单的打包当然不需要考虑修改某(配置)文件.通过inno修改文件的目的在于把安装时相关信息写入文件中,提供其它应用的读取,而这些信息也只能在安装时才能确定,比如安装用户选择 ...
- 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
- php中并发读写文件冲突的解决方案
在这里提供4种高并发读写文件的方案,各有优点,可以根据自己的情况解决php并发读写文件冲突的问题. 对于日IP不高或者说并发数不是很大的应用,一般不用考虑这些!用一般的文件操作方法完全没有问题.但如果 ...
- C#常用IO流与读写文件
.文件系统 ()文件系统类的介绍 文件操作类大都在System.IO命名空间里.FileSystemInfo类是任何文件系统类的基类:FileInfo与File表示文件系统中的文件:Directory ...
- php中并发读写文件冲突的解决方案(文件锁应用示例)
PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适 ...
- 你好,C++(5)如何输出数据到屏幕、从屏幕输入数据与读写文件?
2.2 基本输入/输出流 听过HelloWorld.exe的自我介绍之后,大家已经知道了一个C++程序的任务就是描述数据和处理数据.这两大任务的对象都是数据,可现在的问题是,数据不可能无中生有地产生 ...
- Linux一个简单的读写文件
(1)linux中的文件描述符fd的合法范围是或者一个正正数,不可能是一个负数. (2)open返回的fd程序必须记录好,以后向这个文件的所有操作都要靠这个fd去对应这个文件,最后关闭文件时也需要fd ...
- Qt的Model/View Framework解析(数据是从真正的“肉(raw)”里取得,Model提供肉,所以读写文件、操作数据库、网络通讯等一系列与数据打交道的工作就在model中做了)
最近在看Qt的Model/View Framework,在网上搜了搜,好像中文的除了几篇翻译没有什么有价值的文章.E文的除了Qt的官方介绍,其它文章也很少.看到一个老外在blog中写道Model/Vi ...
- Verilog读写文件
在通过编写Verilog代码实现ram功能时,需要自己先计算寄存器的位数和深度再编写代码. 而如果需要在编写的ram中预置值的话,就需要使用Verilog语言编写程序读写文件,来将相应的数据赋给寄存器 ...
随机推荐
- win10 amd显卡开机黑屏很久
转载自:https://jingyan.baidu.com/article/3c48dd34844e0ce10ae35865.html 升级win10后,使用a卡的小伙伴应该会大为恼火,开机竟然需要黑 ...
- IdentityServer4同时使用多个GrantType进行授权和IdentityModel.Client部分源码解析
首先,介绍一下问题. 由于项目中用户分了三个角色:管理员.代理.会员.其中,代理又分为一级代理.二级代理等,会员也可以相互之间进行推荐. 将用户表分为了两个,管理员和代理都属于后台,在同一张表,会员单 ...
- SIFT算法研究
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://underthehood.blog.51cto.com/2531780/65835 ...
- umi model 注册
model 分两类,一是全局 model,二是页面 model.全局 model 存于 /src/models/ 目录,所有页面都可引用:页面 model 不能被其他页面所引用. 规则如下: src/ ...
- windows使用msi包安装mysql8.0.12
1.前言 利用windows提供的二进制分发包(msi)安装是非常简单的,只要根据提示安装就可以了,和安装普通软件没有什么区别.但是如果想在安装的时候就把规划的配置好,是需要看懂每个步骤到底做什么用, ...
- 如何利用while语句打印“九九乘法口诀表”
需求:输出九九乘法表 plus.py代码如下: i=1 j=1 while i<=9: j=1 while j<=i: print(j,'*',i,'=',str(i*j)+' ',end ...
- jajx 传参 需要 判断的 条件
1.有没有权限. 2.数据类型 对不对 例如 id ,page 传过来时是str 类型, view中处理时需要转换成 int类型. 如果 不能转 就会报错.. 3.查询数据.数据不存在也要报错... ...
- 解决echarts的叠堆折线图数据出现坐标和值对不上的问题
原文:https://blog.csdn.net/qq_36538012/article/details/88889545 ------------------------------- 说一个小bu ...
- BOOTP引导程序协议
我们介绍了一个无盘系统,它在不知道自身 I P地址的情况下,在进行系统引导时能够通过R A R P来获取它的I P地址.然而使用R A R P有两个问题:(1)I P地址是返回的唯一结果:(2)既然R ...
- linux实操_shell自定义函数
基本语法: #定义函数 function 函数名(){ 函数体 } #调用函数 函数名 参数1 参数2... 实例:计算两个数的和. 运行后