欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[转] lzo本地压缩与解压缩实例

程序员文章站 2022-06-13 23:24:53
...
  1. /** 
  2.  * @author HJX 
  3.  * @version 1.0,2013-01-16 
  4.  * @since JDK1.7,Ubuntu-12.04-64bit 
  5.  * 在hadoop环境下运行 
  6.  * 将一个String写入到本地lzo文件中(不是hadoop的hdfs上) 
  7.  * 再从该lzo文件中读取出来并与原String进行校对 
  8.  */  
  9.   
  10. import java.io.BufferedReader;  
  11. import java.io.FileInputStream;  
  12. import java.io.FileNotFoundException;  
  13. import java.io.FileOutputStream;  
  14. import java.io.IOException;  
  15. import java.io.InputStream;  
  16. import java.io.InputStreamReader;  
  17. import java.io.OutputStream;  
  18. import java.util.ArrayList;  
  19. import java.util.List;  
  20.   
  21. import org.apache.hadoop.conf.Configuration;  
  22.   
  23. import com.hadoop.compression.lzo.LzopCodec;  
  24.   
  25. public class LzoCompress {  
  26.   
  27.     /** 
  28.      * @param args 
  29.      */  
  30.     public static void main(String[] args) {  
  31.         //生成数据  
  32.         String dataSource = "abcdefghijklmnopqrstuvwxyz0123456789~!%#^@*#*%$(\n";  
  33.         dataSource = dataSource.concat(dataSource);  
  34.         dataSource = dataSource.concat(dataSource);  
  35.         dataSource = dataSource.concat(dataSource);  
  36. /*        System.out.println("dataSource = " + dataSource);*/  
  37.         String lzoFilePath = "/home/hadoop/LzoCompressTest.lzo";  
  38.           
  39.         //写入到lzo文件,即lzo压缩  
  40.         write2LzoFile(lzoFilePath, getDefaultConf(),dataSource.getBytes());  
  41.         StringBuilder sb = new StringBuilder();  
  42.           
  43.         //读取lzo文件,即lzo解压缩  
  44.         List<String> lines = readLzoFile(lzoFilePath, getDefaultConf());  
  45.         for(String line : lines) {  
  46.             sb.append(line);  
  47.             //LINUX/UNIX 下添加一个换行符  
  48.             sb.append("\n");              
  49. /*            //Windows 下添加一个换行符 
  50.             sb.append("\r\n");*/  
  51.         }  
  52.         if (sb.toString().equals(dataSource)) {  
  53.             System.out.println(sb.toString());  
  54.         } else {  
  55.             System.err.println("Error line : " + sb.toString());  
  56.         }  
  57.     }  
  58.   
  59.     private static Configuration getDefaultConf(){  
  60.         Configuration conf = new Configuration();  
  61.         conf.set("mapred.job.tracker""local");  
  62.         conf.set("fs.default.name""file:///");  
  63.         conf.set("io.compression.codecs""com.hadoop.compression.lzo.LzoCodec");  
  64.         return conf;  
  65.     }  
  66.       
  67.     /** 
  68.      * 写数据到lzo文件,即lzo压缩 
  69.      * @param destLzoFilePath 
  70.      * @param conf 
  71.      * @param datas 
  72.      * @return void 
  73.      */  
  74.     public static void write2LzoFile(String destLzoFilePath,Configuration conf,byte[] datas) {  
  75.         LzopCodec lzo = null;  
  76.         OutputStream out = null;  
  77.           
  78.         try {  
  79. /*          System.setProperty("java.library.path", "/usr/local/hadoop/lib/native/Linux-amd64-64/lib");*/  
  80.             lzo = new LzopCodec();  
  81.             lzo.setConf(conf);  
  82.             out = lzo.createOutputStream(new FileOutputStream(destLzoFilePath));  
  83.             out.write(datas);  
  84.         } catch (FileNotFoundException e) {  
  85.             e.printStackTrace();  
  86.         } catch (IOException e) {  
  87.             e.printStackTrace();  
  88.         } finally {  
  89.             try {  
  90.                 if(out != null) {  
  91.                     out.close();  
  92.                 }  
  93.             } catch (IOException e) {  
  94.                 e.printStackTrace();  
  95.             }  
  96.         }  
  97.     }  
  98.       
  99.     /** 
  100.      * 从lzo文件中读取数据,即lzo解压缩 
  101.      * @param lzoFilePath 
  102.      * @param conf 
  103.      * @return void 
  104.      */  
  105.     public static List<String> readLzoFile(String lzoFilePath,Configuration conf) {  
  106.         LzopCodec lzo = null;  
  107.         InputStream is = null;  
  108.         InputStreamReader isr = null;  
  109.         BufferedReader reader = null;  
  110.         List<String> result = null;  
  111.         String line = null;  
  112.           
  113.         try {  
  114. /*          System.setProperty("java.library.path", "/usr/local/hadoop/lib/native/Linux-amd64-64/lib");*/  
  115.             lzo = new LzopCodec();  
  116.             lzo.setConf(conf);  
  117.             is = lzo.createInputStream(new FileInputStream(lzoFilePath));  
  118.             isr = new InputStreamReader(is);  
  119.             reader = new BufferedReader(isr);  
  120.             result = new ArrayList<String>();  
  121.             while((line = reader.readLine()) != null) {  
  122.                 result.add(line);  
  123.             }  
  124.         } catch (FileNotFoundException e) {  
  125.             e.printStackTrace();  
  126.         } catch (IOException e) {  
  127.             e.printStackTrace();  
  128.         } finally {  
  129.             try {  
  130.                 if (reader != null) {  
  131.                     reader.close();  
  132.                 }  
  133.                 if (isr != null) {  
  134.                     isr.close();  
  135.                 }  
  136.                 if (is != null) {  
  137.                     is.close();  
  138.                 }  
  139.             } catch (IOException e) {  
  140.                 e.printStackTrace();  
  141.             }  
  142.         }  
  143.           
  144.         return result;  
  145.     }  
  146. }  

 

 

 

程序是没有错的,但是一开始运行的时候总会提示无法读取libgplcompression这个库,其实我知道少了哪些库的,分别是
libgplcompression.a
libgplcompression.la
libgplcompression.so
libgplcompression.so.0
libgplcompression.so.0.0.0
可问题是把这些库放在哪里。尝试过把这几个库放在$CLASSPATH下面,但没用。于是查看了错误提示,提示缺少的这个库在 com.hadoop.compression.lzo.GPLNativeCodeLoader这个类里面被引用到,于是看了一下hadoop- lzo-0.45.jar的源文件(当时编译hadoop-lzo-0.45.jar时留下的源文件,在kevinweil-hadoop-lzo- 6bb1b7f/src/java/com/hadoop/compression/lzo/里),GPLNativeCodeLoader.java的 内容是这样的:

 

  1. package com.hadoop.compression.lzo;  
  2.   
  3. import org.apache.commons.logging.Log;  
  4. import org.apache.commons.logging.LogFactory;  
  5.   
  6. public class GPLNativeCodeLoader {  
  7.   
  8.   private static final Log LOG = LogFactory.getLog(GPLNativeCodeLoader.class);  
  9.   private static boolean nativeLibraryLoaded = false;  
  10.   
  11.   static {  
  12.     try {  
  13.       //try to load the lib  
  14.       System.loadLibrary("gplcompression");  
  15.       nativeLibraryLoaded = true;  
  16.       LOG.info("Loaded native gpl library");  
  17.     } catch (Throwable t) {  
  18.       LOG.error("Could not load native gpl library", t);  
  19.       nativeLibraryLoaded = false;  
  20.     }  
  21.   }  
  22.   
  23.   /** 
  24.    * Are the native gpl libraries loaded? 
  25.    * @return true if loaded, otherwise false 
  26.    */  
  27.   public static boolean isNativeCodeLoaded() {  
  28.     return nativeLibraryLoaded;  
  29.   }  
  30.   
  31. }  


这里跟load那个libgplcompression库 有关的语句应该是try语句块里面的那个System.loadLibrary("gplcompression");

 

于是我再查了一下这个loadLibrary的动作到底是怎样的动作。于是在这篇blog里找到了解答:http://blog.csdn.net/forandever/article/details/5983846

 

System.loadLibrary()load的是 java.library.path这一jvm变量所指向的路径中的库。那我只要把那些libgplcompression库 所在的文件夹加入到java.library.path里面不就行了~于是我查找设置java.library.path的方法,

 

方法1:命令行

 

java -Djava.library.path=/path/to/libgplcompression/ ***.class

 

方法2:java语句

 

在程序里加入这么一句,System.setProperty("java.library.path", "/path/to/libgplcompression/");

 

就找了这么2个方法,可是这2个方法都只能临时改变java.library.path的值!

 

除了这2个方法,我找不到别的方法了,累死了,不再找了,索性把libgplcompression这些库给copy到java.library.path指向的文件夹里!

 

copy完后,再次执行,OK了!

 

要获取java.library.path的值,可以用java语句

 

System.out.println(System.getProperty("java.library.path"));

 

我的是

/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
参考资料:

 

 

gpllibcompression库以及hadoop-lzo-0.4.15.jar下载链接

http://pan.baidu.com/s/1mgJQ1tQ