1.文件压缩简单说明
文件压缩有两大好处:可以减少文件存储所需要的磁盘空间,其次是可以加快数据在网络和磁盘上的传输。windows上的压缩算法有好多中,rar,zip等等,同理,在Hadoop中,压缩算法也有多种,下面是Hadoop中常见的压缩算法。
压缩格式总结
压缩格式 | 工具 | 算法 | 文件扩展名 | 是否包含多个文件 | 是否可切分 |
DEFLATE* | N/A | DEFLATE | .deflate | 否 | 否 |
Gzip | gzip | DEFLATE | .gz | 否 | 否 |
bzip2 | bzip2 | bzip2 | .bz2 | 否 | 是 |
LZO | Lzop | LZO | .lzo | 否 | 否 |
所有的压缩算法都需要权衡时间和空间:压缩或者解压速度越快,其代价通常是只能节省少量的磁盘空间!了解Linux压缩算法的都知道,压缩算法提供了一个参数来衡量压缩比(-#),压缩等级为1~9,1表示压缩比最差 ,压缩或者解压最快,9表示压缩比最好,最慢最节省空间!
不同的压缩工具具有不同的压缩特性。gzip是一个通用的压缩工具,在时间/空间的权衡中,居于其余两个中间。N/A一般不用,因为和gzip的压缩性能一样,一般都用gzip。bzip2比gzip更高效,但是压缩速率更更慢一点。bzip2的解压速度比压缩速度快,但与其他压缩格式相比,仍然要慢一些。LZO的优化压缩速度,其速度比gzip等其他压缩工具更快,但压缩率不如gzip。
是否可分割,也就是是否可以搜索数据流的任意位置并进一步往下读取数据。可分割压缩格式尤其使用与MapReduce。
2.对应类
codec实现了一种压缩-解压算法。在Hadoop中,一个对CompressionCodec接口的实现代表一个codec。下表列出了Hadoop实现的codec。
压缩格式 | HadoopCompressionCodec |
DEFLATE | org.apache.hadoop.io.compress.DefaultCodc |
gzip | org.apache.hadoop.io.compress.GzipCodec |
bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
LZO | com.hadoop.compression.lzo.LzopCodec |
3.CompressionCodec
CompressionCodec中包含两个方法用于压缩和解压数据。如果对写入 输出数据流的数据进行压缩,可用CreateOutputStream(OutStream out)方法在底层的数据流中对需要以压缩格式写入的数据(尚未压缩)的数据新建一个CompressionOutputStream对象。相反,如果要对输入数据流中读取数据进行解压缩的时候,则调用CreateInputStream(InputStream in)获取CompressionInputStream,可以通过该方法从底层数据流中读取解压缩后的数据。
实例1:从本地读取一个文件,将压缩数据写入Hadoop中另一个文件中,然后,将压缩数据以标准格数据流输出
1 package cn.roboson.codec;
2
3 import java.io.BufferedInputStream;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.IOException;
8
9 import org.apache.hadoop.conf.Configuration;
10 import org.apache.hadoop.fs.FSDataInputStream;
11 import org.apache.hadoop.fs.FSDataOutputStream;
12 import org.apache.hadoop.fs.FileStatus;
13 import org.apache.hadoop.fs.FileSystem;
14 import org.apache.hadoop.fs.Path;
15 import org.apache.hadoop.io.IOUtils;
16 import org.apache.hadoop.io.compress.CompressionCodec;
17 import org.apache.hadoop.io.compress.CompressionInputStream;
18 import org.apache.hadoop.io.compress.CompressionOutputStream;
19 import org.apache.hadoop.util.ReflectionUtils;
20
21 public class StreamCompressor01 {
22
23 public static void main(String[] args) {
24 String codecClassName="org.apache.hadoop.io.compress.GzipCodec";
25 try {
26 //通过反射实现一个codec
27 Configuration conf = new Configuration();
28 conf.addResource("core-site.xml");
29 Class<?> codecClass = Class.forName(codecClassName);
30 CompressionCodec codec=(CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
31
32 //本地文件路径和Hadoop文件路径
33 String localsrc ="/home/roboson/桌面/README.txt";
34 String hadoopdsc ="/roboson/README";
35
36 //写入前,Hadoop文件系统中/roboson下的文件列表
37 FileSystem fs = FileSystem.get(conf);
38 FileStatus [] files = fs.listStatus(new Path("/roboson/"));
39 System.out.println("文件的个数:"+files.length);
40 for (FileStatus fileStatus : files) {
41 System.out.println(fileStatus.getPath());
42 }
43
44 //获得本地文件的输入流
45 BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(localsrc)));
46 FSDataOutputStream out =fs.create(new Path(hadoopdsc));
47
48 //获得CompressionOutputStream以便对写入 输出数据流的数据进行压缩
49 CompressionOutputStream codecOut = codec.createOutputStream(out);
50
51 //通过IOUtils将本地文件写入到Hadoop文件系统中
52 IOUtils.copyBytes(in, codecOut, conf,true);
53
54 //写入后,Hadoop文件系统中/roboson下的文件列表
55 files = fs.listStatus(new Path("/roboson/"));
56 System.out.println("文件的个数:"+files.length);
57 for (FileStatus fileStatus : files) {
58 System.out.println(fileStatus.getPath());
59 }
60
61 //获得输入数据流
62 FSDataInputStream dIn = fs.open(new Path(hadoopdsc));
63
64 //获得CompressionInputStream以便对输入数据流中读取的数据进行解压
65 CompressionInputStream codecIn = codec.createInputStream(dIn);
66
67 //通过IOUtils将数据输出到控制台
68 IOUtils.copyBytes(codecIn, System.out, conf,true);
69 } catch (ClassNotFoundException e) {
70 // TODO Auto-generated catch block
71 e.printStackTrace();
72 } catch (FileNotFoundException e) {
73 // TODO Auto-generated catch block
74 e.printStackTrace();
75 } catch (IOException e) {
76 // TODO Auto-generated catch block
77 e.printStackTrace();
78 }
79
80 }
81 }
运行结果: