Hadoop————Hadoop中的文件类型——学习笔记

课程结构图:
在这里插入图片描述
OutLine
序列文件SequenceFile
排序的序列文件MapFile

SequenceFile

— 可以作为小文件的容器,封装小文件
— 用于存储键值对的二进制文件格式
— 支持压缩
— 保持可分割(可拆分)(拆分标志)
— 支持二进制的键和值
— 在HDFS中获得更高的存储效率
— 用于链接多个Hadoop作业

序列文件SequenceFile有3种类型
— 未压缩
— 记录(Record)压缩
— 块(Block)压缩




它的来源的包是:
org.apache.hadoop.io.SequenceFile
— SequenceFile的每条记录是可序列化的字符数组
— 存储结构上,SequenceFile由一个Header后跟多条Record组成.


Header
— 包含Key classname, Value classname, 存储压缩算法,用户自定义元数据等信息
— 还包含了一些同步标识,用于快速定位到记录的边界


每条Record以键值对的方式进行存储 --- 记录的长度,Key的长度,Key值和Value值,并且Value值得结构取决于该记录是否被压缩 --- 一般记录分为未压缩、记录压缩和块压缩

在这里插入图片描述

Block Compression
— 将一连串得record组织到一起,统一压缩成一个block
— block信息主要存储了:块所包含的记录数,每条记录Key长度的集合,每条记录Key值的集合,每条记录Value的集合,每条记录Value长度的集合和每条记录Value值的集合。
在这里插入图片描述
实践:
SequenceFile.Writer 写
SequenceFile.Reader 读
SequenceFile.Sorter 排序

#SequenceFileWriteFile#

package ex5;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.SequenceFile.CompressionType;
import org.apache.hadoop.io.Text;

public class SequenceFileWriteFile {
	private static String[] myValue = { 
		"hello world", 
		"bye world", 
		"hello hadoop", 
		"bye hadoop" 
	};

	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		String uri = "testdata/sqfile/sq1";
		Configuration conf = new Configuration();
		//在window中运行,关闭读取本地gzip压缩库
		conf.setBoolean("io.native.lib.available",false);
		FileSystem fs = FileSystem.getLocal(conf);
		Path path = new Path(uri);
		IntWritable key = new IntWritable();
		Text value = new Text();
		SequenceFile.Writer writer = null;
		try {
			writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass(),CompressionType.NONE);
//			writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass(),CompressionType.RECORD);
//			writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass(),CompressionType.BLOCK);
			for (int i = 0; i < 500; i++) {
				key.set(500 - i);
				value.set(myValue[i % myValue.length]);
				System.out.printf("[%s]\t%s\t%s\n", writer.getLength(),key,value);
				writer.append(key, value);
			}
		} finally {
			IOUtils.closeStream(writer);
		}
	}
}

运行结果:
在这里插入图片描述

#SequenceFileReadFile#
代码:
对于读取文件,这里由几个需要注意的的地方;
举一个理解,对于下面这个程序来说,如果我们想要读取:500 hello world的话,假如我们采用指定特定的位置进行读取的话,我们应该指定的位置是
128;如果我们指定的位置是非边界位置,就会抛出异常IOEexception.

package ex5;

import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;

public class SequenceFileReadFile {
	public static void main(String[] args) throws IOException {
		String uri = "testdata/sqfile/sq1";
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.getLocal(conf);
		Path path = new Path(uri);
		SequenceFile.Reader reader = null;
		try {
			reader = new SequenceFile.Reader(fs, path, conf);     //创建这个工具,给出文件系统,路径,配置.
			//reader.getKeyClass(),getValueClass()得到key和value的类型,并通过ReflectionUtils实例化
			Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);   //key值的内容用反射的方法来实例化.
			Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf);
			long position = reader.getPosition();     //用来记录读取的边界的位置
			while (reader.next(key, value)) {         //使用reader.next的方法来读取所有的数据
				String syncSeen = reader.syncSeen() ? "*" : "";      //如果碰到了边界就把sncSeen赋值为*
				System.out.printf("[%s%s]\t%s\t%s\n", position, syncSeen, key, value);   //输出的时候输出了位置,遇到边界就输出*号,最后输出key和value
				position = reader.getPosition(); // beginning of next record
			}
			
			//指向特定的位置的读取
			reader.seek(128L);     //指向非边界位置会报错. IOException
			reader.next(key, value);
			System.out.printf("[%s]%s\t%s\n", reader.getPosition(), key, value);
			
			//下面的指定是得到一个里我们指定位置最近的同步标志的位置,然后得到里同步标志最近的下一个位置,由于是往下读的,所以我们这里输出的应该是2070位置上的数
			reader.sync(288L);
			reader.next(key, value);
			System.out.printf("[%s]%s\t%s\n", reader.getPosition(), key, value);
			
			
		} finally {
			IOUtils.closeStream(reader);
		}
	}
}

运行效果:
在这里插入图片描述

MapFile

org.apache.hadoop.io.MapFile
— MapFile是排序后的SequenceFile

  1. MapFile由两部分组成
  2. Data
  3. Index
    — 主要记录了每个Record的key值,以及该Record在文件种的偏移位置
    — 在MapFile被访问的时候,索引文件会被加载到内存

MapFile的扩展:
1. SetFile
— 存储Writable的集合
2. ArrayFile
— Key是整数,可以做下标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值