hadoop2.x之IO:压缩和解压缩
来源:互联网 发布:淘宝店铺处罚规则 编辑:程序博客网 时间:2024/06/11 22:04
文件压缩可以降低存储需要的空间,并且在传输过程中加快传输速度。因此对于大量数据的处理时,压缩是十分重要的。我们考虑一下Hadoop在文件中的压缩用法。
有许多压缩方式,如下:
压缩主要考虑时间和速度,在上面的三种压缩工具中都提供了对压缩时间和压缩空间的调整参数。-1是为优化压缩速度,-9是优化压缩空间,1~9中间其他的参数介于二者之间。
另外不同的压缩有着不同的特性,
- bzip2压缩能力强,但压缩时间慢。他的解压较快
- gzip压缩能力和压缩时间介于bzip2和lzop之间
因此不同的情况有着不同的使用。
1. 使用CompressionCodec接口实现压缩和解压缩
在Hadoop中CompressionCodec接口定义了压缩和解压缩的方法。其包含许多具体的实现。
实现如下:
CompressionCodec中包含两个函数用于压缩和解压:
createOutputStream(OutputStream out)
压缩out中的内容,并返回一个CompressionOutputStream对象来包含压缩结果。createInputStream(InputStream in)
解压in中的内容,并返回一个CompressionInputStream对象来包含解压结果。
2. 压缩程序
编写一个压缩程序:
import java.io.IOException;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataInputStream;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.compress.CompressionCodec;import org.apache.hadoop.io.compress.CompressionOutputStream;import org.apache.hadoop.io.compress.GzipCodec;import org.apache.hadoop.util.ReflectionUtils;public class GZipCodec { public static void main(String[] args) throws IOException { String srcUrl = args[0]; String targetUrl = args[1]; Configuration conf = new Configuration(); FileSystem inFs = FileSystem.get(URI.create(srcUrl),conf); FileSystem outFs = FileSystem.get(URI.create(targetUrl),conf); CompressionCodec codec = ReflectionUtils.newInstance(GzipCodec.class,conf); FSDataInputStream inputStream = inFs.open(new Path(srcUrl)); CompressionOutputStream outputStream = codec.createOutputStream(outFs.create(new Path(targetUrl))); IOUtils.copyBytes(inputStream, outputStream, 4096,false); outputStream.finish(); IOUtils.closeStream(outputStream); IOUtils.closeStream(inputStream); System.out.println("输入文件的大小"+inFs.getFileStatus(new Path(srcUrl)).getLen()+"b"); System.out.println("输出文件的大小"+outFs.getFileStatus(new Path(targetUrl)).getLen()+"b"); System.out.printf("压缩率为%.2f%%\n",100*(1.0*outFs.getFileStatus(new Path(targetUrl)).getLen()/inFs.getFileStatus(new Path(srcUrl)).getLen())); }}
在hadoop下运行:
[grid@tiny01 input]$ hadoop GZipCodec file:///home/grid/input/data.txt file:///home/grid/input/data.gz17/07/28 01:49:03 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable输入文件的大小49252b输出文件的大小2362b压缩率为4.80%
可以看到压缩的还是很不错的。我们使用linux的gzip命令压缩一下
[grid@tiny01 input]$ md5sum data.txte8d882c5b4f4c8d6952d8a88a4d65c52 data.txt[grid@tiny01 input]$ gzip -d data.gz[grid@tiny01 input]$ md5sum datae8d882c5b4f4c8d6952d8a88a4d65c52 data
我们可以看到压缩的和解压的是同一个文件。(md5sum在cyrus-sasl-md5包下)
关于
17/07/28 01:49:03 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
是因为Java默认查询原生类库(native),如果找到则会自动加载,如果没有找到就会出现这个警告。
3. 解压程序
import java.io.IOException;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataInputStream;import org.apache.hadoop.fs.FSDataOutputStream;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.compress.CompressionCodec;import org.apache.hadoop.io.compress.CompressionInputStream;import org.apache.hadoop.io.compress.CompressionOutputStream;import org.apache.hadoop.io.compress.GzipCodec;import org.apache.hadoop.util.ReflectionUtils;public class GZipDCodec { public static void main(String[] args) throws IOException { String srcUrl = args[0]; String targetUrl = args[1]; Configuration conf = new Configuration(); FileSystem inFs = FileSystem.get(URI.create(srcUrl),conf); FileSystem outFs = FileSystem.get(URI.create(targetUrl),conf); CompressionCodec codec = ReflectionUtils.newInstance(GzipCodec.class,conf); FSDataOutputStream outputStream = outFs.create(new Path(targetUrl)); CompressionInputStream inputStream = codec.createInputStream(inFs.open(new Path(srcUrl))); IOUtils.copyBytes(inputStream, outputStream, 4096,false); outputStream.close(); inputStream.close(); System.out.println("输入文件的大小"+inFs.getFileStatus(new Path(srcUrl)).getLen()+"b"); System.out.println("输出文件的大小"+outFs.getFileStatus(new Path(targetUrl)).getLen()+"b"); System.out.printf("解压率为%.2f%%\n",100*(1.0*outFs.getFileStatus(new Path(targetUrl)).getLen()/inFs.getFileStatus(new Path(srcUrl)).getLen())); }}
运行可得
[grid@tiny01 input]$ ll总用量 64-rw-r--r--. 1 grid grid 2362 7月 28 04:55 data.gz-rw-rw-r--. 1 grid grid 49252 7月 27 23:46 data.txt-rw-r--r--. 1 grid grid 8 7月 27 04:03 word2.txt-rw-rw-r--. 1 grid grid 11 6月 25 18:31 word.txt[grid@tiny01 input]$ hadoop GZipDCodec file:///home/grid/input/data.gz file:///home/grid/input/data1.txt17/07/28 16:34:01 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable17/07/28 16:34:01 INFO compress.CodecPool: Got brand-new decompressor [.gz]输入文件的大小2362b输出文件的大小49252b解压率为2085.18%[grid@tiny01 input]$ ll总用量 116-rw-r--r--. 1 grid grid 49252 7月 28 16:34 data1.txt-rw-r--r--. 1 grid grid 2362 7月 28 04:55 data.gz-rw-rw-r--. 1 grid grid 49252 7月 27 23:46 data.txt-rw-r--r--. 1 grid grid 8 7月 27 04:03 word2.txt-rw-rw-r--. 1 grid grid 11 6月 25 18:31 word.txt
4.根据文件拓展名推测解压方式
hadoop还提供了一个通过拓展名猜测压缩算法的方法:CompressionCodecFactory类中的getCodec()方法。
import java.io.InputStream;import java.io.OutputStream;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.compress.CompressionCodec;import org.apache.hadoop.io.compress.CompressionCodecFactory;public class DefaultDCodec { public static void main(String[] args) throws Exception { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri),conf); Path inputPath = new Path(uri); CompressionCodecFactory factory = new CompressionCodecFactory(conf); CompressionCodec codec = factory.getCodec(inputPath); if(codec == null){ System.err.println("没有找到压缩方式:"+uri); System.exit(1); } String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension()); InputStream in = null; OutputStream out = null; try { in = codec.createInputStream(fs.open(inputPath)); out = fs.create(new Path(outputUri)); IOUtils.copyBytes(in, out,conf); } catch (Exception e) { IOUtils.closeStream(in); IOUtils.closeStream(out); } }}
运行结果:
[grid@tiny01 input]$ ll总用量 64-rw-r--r--. 1 grid grid 2362 7月 28 04:55 data.gz-rw-rw-r--. 1 grid grid 49252 7月 27 23:46 data.txt-rw-r--r--. 1 grid grid 8 7月 27 04:03 word2.txt-rw-rw-r--. 1 grid grid 11 6月 25 18:31 word.txt[grid@tiny01 input]$ hadoop DefaultDCodec file:///home/grid/input/data.gz17/07/28 21:48:19 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable17/07/28 21:48:20 INFO compress.CodecPool: Got brand-new decompressor [.gz][grid@tiny01 input]$ ll总用量 116-rw-r--r--. 1 grid grid 49252 7月 28 21:48 data-rw-r--r--. 1 grid grid 2362 7月 28 04:55 data.gz-rw-rw-r--. 1 grid grid 49252 7月 27 23:46 data.txt-rw-r--r--. 1 grid grid 8 7月 27 04:03 word2.txt-rw-rw-r--. 1 grid grid 11 6月 25 18:31 word.txt
5.参考资料
[1] Hadoop:The Definitive Guide,Third Edition, by Tom White. Copyright 2013 Tom White,978-1-449-31152-0
阅读全文
0 0
- hadoop2.x之IO:压缩和解压缩
- hadoop2.x之IO:MapReduce压缩
- 【Java】IO操作之使用zip包压缩和解压缩文件
- IO操作之使用zip包压缩和解压缩文件
- NETCF开发之文件压缩和解压缩
- iOS之SSZipArchive压缩和解压缩
- Centos之压缩和解压缩命令
- Centos之压缩和解压缩命令
- Centos之压缩和解压缩命令
- 压缩和解压缩
- 压缩和解压缩
- 压缩和解压缩
- 压缩和解压缩类
- linux压缩和解压缩
- 关于压缩和解压缩
- Linux 压缩和解压缩
- 压缩和解压缩
- java 压缩和解压缩
- 【javascript设计模式】2.Module(模块)模式
- shell脚本之变量
- Java动态代理机制详解
- codeforces 669A Little Artem and Presents
- 在idea中出现 错误Servlet.init() for servlet springmvc threw exception
- hadoop2.x之IO:压缩和解压缩
- pat:L1-039. 古风排版
- Java面试题大汇总
- HDU
- 从大三狗到工作狗的历程
- Python-Pandas(3)数据预处理
- 二分查找
- CSU 1203: Super-increasing sequence 水题
- 博弈——Good Luck in CET-4 Everybody!