转载请注明出处:http://www.cnblogs.com/zhengrunjian/p/4527220.html

所有源码在github上,https://github.com/lastsweetop/styhadoop

1简介

codec其实就是coder和decoder两个单词的词头组成的缩略词。CompressionCodec定义了压缩和解压接口,我们这里讲的codec就是实现了CompressionCodec接口的一些压缩格式的类,下面是这些类的列表:

2使用CompressionCodes解压缩

CompressionCodec有两个方法可以方便的压缩和解压。
压缩:通过createOutputStream(OutputStream out)方法获得CompressionOutputStream对象
解压:通过createInputStream(InputStream in)方法获得CompressionInputStream对象
压缩的示例代码
  1. package com.sweetop.styhadoop;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.io.IOUtils;
  4. import org.apache.hadoop.io.compress.CompressionCodec;
  5. import org.apache.hadoop.io.compress.CompressionOutputStream;
  6. import org.apache.hadoop.util.ReflectionUtils;
  7. /**
  8. * Created with IntelliJ IDEA.
  9. * User: lastsweetop
  10. * Date: 13-6-25
  11. * Time: 下午10:09
  12. * To change this template use File | Settings | File Templates.
  13. */
  14. public class StreamCompressor {
  15. public static void main(String[] args) throws Exception {
  16. String codecClassName = args[0];
  17. Class<?> codecClass = Class.forName(codecClassName);
  18. Configuration conf = new Configuration();
  19. CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
  20. CompressionOutputStream out = codec.createOutputStream(System.out);
  21. IOUtils.copyBytes(System.in, out, 4096, false);
  22. out.finish();
  23. }
  24. }
从命令行接受一个CompressionCodec实现类的参数,然后通过ReflectionUtils把实例化这个类,调用CompressionCodec的接口方法对标准输出流进行封装,封装成一个压缩流,通过IOUtils类的copyBytes方法把标准输入流拷贝到压缩流中,最后调用CompressionCodec的finish方法,完成压缩。
再来看下命令行:
  1. echo "Hello lastsweetop" | ~/hadoop/bin/hadoop com.sweetop.styhadoop.StreamCompressor  org.apache.hadoop.io.compress.GzipCodec | gunzip -

使用GzipCodec类来压缩“Hello lastsweetop”,然后再通过gunzip工具解压。

我们来看一下输出:
  1. [exec] 13/06/26 20:01:53 INFO util.NativeCodeLoader: Loaded the native-hadoop library
  2. [exec] 13/06/26 20:01:53 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
  3. [exec] Hello lastsweetop

3使用CompressionCodecFactory解压缩

如果你想读取一个被压缩的文件的话,首先你得先通过扩展名判断该用哪种codec,可以看下【hadoop】——压缩工具比较中得对应关系。
当然有更简便得办法,CompressionCodecFactory已经帮你把这件事做了,通过传入一个Path调用它得getCodec方法,即可获得相应得codec。我们来看下代码
  1. package com.sweetop.styhadoop;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.fs.FileSystem;
  4. import org.apache.hadoop.fs.Path;
  5. import org.apache.hadoop.io.IOUtils;
  6. import org.apache.hadoop.io.compress.CompressionCodec;
  7. import org.apache.hadoop.io.compress.CompressionCodecFactory;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.OutputStream;
  11. import java.net.URI;
  12. /**
  13. * Created with IntelliJ IDEA.
  14. * User: lastsweetop
  15. * Date: 13-6-26
  16. * Time: 下午10:03
  17. * To change this template use File | Settings | File Templates.
  18. */
  19. public class FileDecompressor {
  20. public static void main(String[] args) throws Exception {
  21. String uri = args[0];
  22. Configuration conf = new Configuration();
  23. FileSystem fs = FileSystem.get(URI.create(uri), conf);
  24. Path inputPath = new Path(uri);
  25. CompressionCodecFactory factory = new CompressionCodecFactory(conf);
  26. CompressionCodec codec = factory.getCodec(inputPath);
  27. if (codec == null) {
  28. System.out.println("No codec found for " + uri);
  29. System.exit(1);
  30. }
  31. String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
  32. InputStream in = null;
  33. OutputStream out = null;
  34. try {
  35. in = codec.createInputStream(fs.open(inputPath));
  36. out = fs.create(new Path(outputUri));
  37. IOUtils.copyBytes(in,out,conf);
  38. } finally {
  39. IOUtils.closeStream(in);
  40. IOUtils.closeStream(out);
  41. }
  42. }
  43. }

注意看下removeSuffix方法,这是一个静态方法,它可以将文件的后缀去掉,然后我们将这个路径做为解压的输出路径。CompressionCodecFactory能找到的codec也是有限的,默认只有三种org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.DefaultCodec,如果想添加其他的codec你需要更改io.compression.codecs属性,并注册codec。

 

4原生库

现在越来越多原生库的概念,hdfs的codec也不例外,原生库可以极大的提升性能比如gzip的原生库解压提高50%,压缩提高10%,但不是所有codec都有原生库的,而一些codec只有原生库。我们来看下列表:
linux下,hadoop以前提前编译好了32位的原生库和64位的原生库,我们看下:
  1. [hadoop@namenode native]$pwd
  2. /home/hadoop/hadoop/lib/native
  3. [hadoop@namenode native]$ls -ls
  4. total 8
  5. 4 drwxrwxrwx 2 root root 4096 Nov 14  2012 Linux-amd64-64
  6. 4 drwxrwxrwx 2 root root 4096 Nov 14  2012 Linux-i386-32

如果是其他平台的话,你就需要自己编译了,详细步骤请看这里http://wiki.apache.org/hadoop/NativeHadoop

java原生库的路径可以通过java.library.path指定,在bin目录下,hadoop的启动脚本已经指定,如果你不用这个脚本,那么你就需要在你的程序中指定了,hadoop脚本中指定原生库路径的片段:
  1. if [ -d "${HADOOP_HOME}/build/native" -o -d "${HADOOP_HOME}/lib/native" -o -e "${HADOOP_PREFIX}/lib/libhadoop.a" ]; then
  2. if [ -d "$HADOOP_HOME/build/native" ]; then
  3. JAVA_LIBRARY_PATH=${HADOOP_HOME}/build/native/${JAVA_PLATFORM}/lib
  4. fi
  5. if [ -d "${HADOOP_HOME}/lib/native" ]; then
  6. if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
  7. JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}:${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
  8. else
  9. JAVA_LIBRARY_PATH=${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
  10. fi
  11. fi
  12. if [ -e "${HADOOP_PREFIX}/lib/libhadoop.a" ]; then
  13. JAVA_LIBRARY_PATH=${HADOOP_PREFIX}/lib
  14. fi
  15. fi

hadoop会去查找对应的原生库,并且自动加载,你不需要关心这些设置。但某些时候你不想使用原生库,比如调试一些bug的时候,那么可以通过hadoop.native.lib设置为false来实现。

如果你用原生库做大量的压缩和解压的话可以考虑用CodecPool,有点像连接池,这样你就无需频繁的去创建codec对象。
  1. package com.sweetop.styhadoop;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.io.IOUtils;
  4. import org.apache.hadoop.io.compress.CodecPool;
  5. import org.apache.hadoop.io.compress.CompressionCodec;
  6. import org.apache.hadoop.io.compress.CompressionOutputStream;
  7. import org.apache.hadoop.io.compress.Compressor;
  8. import org.apache.hadoop.util.ReflectionUtils;
  9. /**
  10. * Created with IntelliJ IDEA.
  11. * User: lastsweetop
  12. * Date: 13-6-27
  13. * Time: 上午11:53
  14. * To change this template use File | Settings | File Templates.
  15. */
  16. public class PooledStreamCompressor {
  17. public static void main(String[] args) throws Exception {
  18. String codecClassName = args[0];
  19. Class<?> codecClass = Class.forName(codecClassName);
  20. Configuration conf = new Configuration();
  21. CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
  22. Compressor compressor = null;
  23. try {
  24. compressor = CodecPool.getCompressor(codec);
  25. CompressionOutputStream out = codec.createOutputStream(System.out, compressor);
  26. IOUtils.copyBytes(System.in, out, 4096, false);
  27. out.finish();
  28. } finally {
  29. CodecPool.returnCompressor(compressor);
  30. }
  31. }
  32. }

代码比较容易理解,通过CodecPool的getCompressor方法获得Compressor对象,该方法需要传入一个codec,然后Compressor对象在createOutputStream中使用,使用完毕后再通过returnCompressor放回去。

输出结果如下:
  1. [exec] 13/06/27 12:00:06 INFO util.NativeCodeLoader: Loaded the native-hadoop library
  2. [exec] 13/06/27 12:00:06 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
  3. [exec] 13/06/27 12:00:06 INFO compress.CodecPool: Got brand-new compressor
  4. [exec] Hello lastsweetop    

    转载请注明出处:http://blog.csdn.net/lastsweetop/article/details/9173061

【hadoop】——HDFS解压缩实现的更多相关文章

  1. [转]hadoop hdfs常用命令

    FROM : http://www.2cto.com/database/201303/198460.html hadoop hdfs常用命令   hadoop常用命令:  hadoop fs  查看H ...

  2. Hadoop HDFS安装、环境配置

    hadoop安装 进入Xftp将hadoop-2.7.3.tar.gz 复制到自己的虚拟机系统下的放软件的地方,我的是/soft/software 在虚拟机系统装软件文件里,进行解压缩并重命名 进入p ...

  3. Hadoop HDFS常用操作命令

    hadoop常用命令:hadoop fs查看Hadoop HDFS支持的所有命令 hadoop fs –ls列出目录及文件信息 hadoop fs –lsr循环列出目录.子目录及文件信息 hadoop ...

  4. 基于key/value+Hadoop HDFS 设计的存储系统的shell命令接口

    对于hadoop HDFS 中的全部命令进行解析(当中操作流程是自己的想法有不允许见欢迎大家指正) 接口名称 功能 操作流程 get 将文件拷贝到本地文件系统 . 假设指定了多个源文件,本地目的端必须 ...

  5. Hadoop HDFS 用户指南

    This document is a starting point for users working with Hadoop Distributed File System (HDFS) eithe ...

  6. Hadoop HDFS负载均衡

    Hadoop HDFS负载均衡 转载请注明出处:http://www.cnblogs.com/BYRans/ Hadoop HDFS Hadoop 分布式文件系统(Hadoop Distributed ...

  7. Hive:org.apache.hadoop.hdfs.protocol.NSQuotaExceededException: The NameSpace quota (directories and files) of directory /mydir is exceeded: quota=100000 file count=100001

    集群中遇到了文件个数超出限制的错误: 0)昨天晚上spark 任务突然抛出了异常:org.apache.hadoop.hdfs.protocol.NSQuotaExceededException: T ...

  8. Hadoop程序运行中的Error(1)-Error: org.apache.hadoop.hdfs.BlockMissingException

    15/03/18 09:59:21 INFO mapreduce.Job: Task Id : attempt_1426641074924_0002_m_000000_2, Status : FAIL ...

  9. Hadoop HDFS编程 API入门系列之HDFS_HA(五)

    不多说,直接上代码. 代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs3; import java.io.FileInputStream;import ...

  10. Hadoop HDFS编程 API入门系列之简单综合版本1(四)

    不多说,直接上代码. 代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs4; import java.io.IOException; import ja ...

随机推荐

  1. PHP程序员7小时学会Kotlin系列

    这是我尝试给自己一个目标去学会一门新语言的方法.正在创作中,敬请期待! 提纲 第一小时 概念 第二小时 基础 第三小时 函数 第四小时 类与对象 第五小时 类与对象二 第六小时 DSL 第七小时 工程 ...

  2. MySQL高效分页解决方案集(转)

    很久以前的一次面试中,被面试官问到这个问题,由于平时用到的分页方法不多,只从索引.分表.使用子查询精准定位偏移以外,没有使用到其它方法. 后来在看其它博客看到了一些不同的方案,也一直没有整理.今天有时 ...

  3. 【转】ubuntu源码编译安装php常见错误解决办法

    ./configure -prefix=/usr/local/php -with-config-file-path=/etc -with-mysql=mysqlnd -with-mysqli=mysq ...

  4. WebDriver多线程并发

    要想多线程并发的运行WebDriver,必须同时满足2个条件,首先你的测试程序是多线程,其次需要用到Selenium Server.下载位置如下图: 下载下来后是一个jar包,需要在命令行中运行.里面 ...

  5. 如何用.NET生成二维码?

    二维码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,国外对二维码技术的研究始于20世纪80年代末,在二维码符号表示技术研究方面已研制出多种码制,常见的有P ...

  6. Remodal – 支持 Hash 追踪的响应式模态窗口

    Remodal 是一个扁平化,响应式,轻量而且容易定制的模态窗口插件,支持使用声明状态和 Hash 跟踪.您可以轻松地定义为模态弹窗定义背景景容器(如模糊效果).支持所有现代的浏览器. 您可能感兴趣的 ...

  7. 【HTML点滴】WWW简介

    www 什么是WWW www(world wide web),又称为万维网,或通常称为web,是一个基于超文本方式的信息检索服务工具. WWW的工作模式 C/S结构(client/server结构), ...

  8. jQ函数after、append、appendTo的区别

    1.after函数定义和用法:after() 方法在被选元素后插入指定的内容.参考:http://keleyi.com/a/bjac/cfyxd60g.htm 语法:$(selector).after ...

  9. php 过滤英文标点符号 过滤中文标点符号

    php 过滤英文标点符号 过滤中文标点符号 代码 function filter_mark($text){ if(trim($text)=='')return ''; $text=preg_repla ...

  10. dispatch

    GCD提供了并管理着若干FIFO队列(queues),可以通过block的形式向这些FIFO序列提交任务.GCD同时维护着一个线程池,所有的任务在线程池的线程运行. 系统提供的队列 main queu ...