文档章节

Java压缩技术(一) ZLib

村长大神
 村长大神
发布于 2014/11/05 13:25
字数 1549
阅读 67
收藏 5
应好友需要,整理一下Java的压缩算法,先从ZLib开始。

相关链接:
Java压缩技术(一) ZLib
Java压缩技术(二) ZIP压缩——Java原生实现
Java压缩技术(三) ZIP解压缩——Java原生实现
Java压缩技术(四) GZIP——Java原生实现
Java压缩技术(五) GZIP相关——浏览器解析
Java压缩技术(六) BZIP2——Commons实现
Java压缩技术(七) TAR——Commons实现

有关ZLib可参见官方主页 http://www.zlib.net/
ZLib可以简单的理解为压缩/解压缩算法,它与ZIP、RAR等归档算法有所不同,与bzip2比较接近。

压缩工具代码如下:
Java代码 复制代码  收藏代码
  1. /**  
  2.  * 2009-9-9  
  3.  */  
  4. package org.zlex.commons.io;   
  5.   
  6. import java.io.ByteArrayOutputStream;   
  7. import java.io.IOException;   
  8. import java.io.InputStream;   
  9. import java.io.OutputStream;   
  10. import java.util.zip.Deflater;   
  11. import java.util.zip.DeflaterOutputStream;   
  12. import java.util.zip.Inflater;   
  13. import java.util.zip.InflaterInputStream;   
  14.   
  15. /**  
  16.  * ZLib压缩工具  
  17.  *   
  18.  * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>  
  19.  * @version 1.0  
  20.  * @since 1.0  
  21.  */  
  22. public abstract class ZLibUtils {   
  23.   
  24.     /**  
  25.      * 压缩  
  26.      *   
  27.      * @param data  
  28.      *            待压缩数据  
  29.      * @return byte[] 压缩后的数据  
  30.      */  
  31.     public static byte[] compress(byte[] data) {   
  32.         byte[] output = new byte[0];   
  33.   
  34.         Deflater compresser = new Deflater();   
  35.   
  36.         compresser.reset();   
  37.         compresser.setInput(data);   
  38.         compresser.finish();   
  39.         ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);   
  40.         try {   
  41.             byte[] buf = new byte[1024];   
  42.             while (!compresser.finished()) {   
  43.                 int i = compresser.deflate(buf);   
  44.                 bos.write(buf, 0, i);   
  45.             }   
  46.             output = bos.toByteArray();   
  47.         } catch (Exception e) {   
  48.             output = data;   
  49.             e.printStackTrace();   
  50.         } finally {   
  51.             try {   
  52.                 bos.close();   
  53.             } catch (IOException e) {   
  54.                 e.printStackTrace();   
  55.             }   
  56.         }   
  57.         compresser.end();   
  58.         return output;   
  59.     }   
  60.   
  61.     /**  
  62.      * 压缩  
  63.      *   
  64.      * @param data  
  65.      *            待压缩数据  
  66.      *   
  67.      * @param os  
  68.      *            输出流  
  69.      */  
  70.     public static void compress(byte[] data, OutputStream os) {   
  71.         DeflaterOutputStream dos = new DeflaterOutputStream(os);   
  72.   
  73.         try {   
  74.             dos.write(data, 0, data.length);   
  75.   
  76.             dos.finish();   
  77.   
  78.             dos.flush();   
  79.         } catch (IOException e) {   
  80.             e.printStackTrace();   
  81.         }   
  82.     }   
  83.   
  84.     /**  
  85.      * 解压缩  
  86.      *   
  87.      * @param data  
  88.      *            待压缩的数据  
  89.      * @return byte[] 解压缩后的数据  
  90.      */  
  91.     public static byte[] decompress(byte[] data) {   
  92.         byte[] output = new byte[0];   
  93.   
  94.         Inflater decompresser = new Inflater();   
  95.         decompresser.reset();   
  96.         decompresser.setInput(data);   
  97.   
  98.         ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);   
  99.         try {   
  100.             byte[] buf = new byte[1024];   
  101.             while (!decompresser.finished()) {   
  102.                 int i = decompresser.inflate(buf);   
  103.                 o.write(buf, 0, i);   
  104.             }   
  105.             output = o.toByteArray();   
  106.         } catch (Exception e) {   
  107.             output = data;   
  108.             e.printStackTrace();   
  109.         } finally {   
  110.             try {   
  111.                 o.close();   
  112.             } catch (IOException e) {   
  113.                 e.printStackTrace();   
  114.             }   
  115.         }   
  116.   
  117.         decompresser.end();   
  118.         return output;   
  119.     }   
  120.   
  121.     /**  
  122.      * 解压缩  
  123.      *   
  124.      * @param is  
  125.      *            输入流  
  126.      * @return byte[] 解压缩后的数据  
  127.      */  
  128.     public static byte[] decompress(InputStream is) {   
  129.         InflaterInputStream iis = new InflaterInputStream(is);   
  130.         ByteArrayOutputStream o = new ByteArrayOutputStream(1024);   
  131.         try {   
  132.             int i = 1024;   
  133.             byte[] buf = new byte[i];   
  134.   
  135.             while ((i = iis.read(buf, 0, i)) > 0) {   
  136.                 o.write(buf, 0, i);   
  137.             }   
  138.   
  139.         } catch (IOException e) {   
  140.             e.printStackTrace();   
  141.         }   
  142.         return o.toByteArray();   
  143.     }   
  144. }  
/**
 * 2009-9-9
 */
package org.zlex.commons.io;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

/**
 * ZLib压缩工具
 * 
 * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>
 * @version 1.0
 * @since 1.0
 */
public abstract class ZLibUtils {

	/**
	 * 压缩
	 * 
	 * @param data
	 *            待压缩数据
	 * @return byte[] 压缩后的数据
	 */
	public static byte[] compress(byte[] data) {
		byte[] output = new byte[0];

		Deflater compresser = new Deflater();

		compresser.reset();
		compresser.setInput(data);
		compresser.finish();
		ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
		try {
			byte[] buf = new byte[1024];
			while (!compresser.finished()) {
				int i = compresser.deflate(buf);
				bos.write(buf, 0, i);
			}
			output = bos.toByteArray();
		} catch (Exception e) {
			output = data;
			e.printStackTrace();
		} finally {
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		compresser.end();
		return output;
	}

	/**
	 * 压缩
	 * 
	 * @param data
	 *            待压缩数据
	 * 
	 * @param os
	 *            输出流
	 */
	public static void compress(byte[] data, OutputStream os) {
		DeflaterOutputStream dos = new DeflaterOutputStream(os);

		try {
			dos.write(data, 0, data.length);

			dos.finish();

			dos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 解压缩
	 * 
	 * @param data
	 *            待压缩的数据
	 * @return byte[] 解压缩后的数据
	 */
	public static byte[] decompress(byte[] data) {
		byte[] output = new byte[0];

		Inflater decompresser = new Inflater();
		decompresser.reset();
		decompresser.setInput(data);

		ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
		try {
			byte[] buf = new byte[1024];
			while (!decompresser.finished()) {
				int i = decompresser.inflate(buf);
				o.write(buf, 0, i);
			}
			output = o.toByteArray();
		} catch (Exception e) {
			output = data;
			e.printStackTrace();
		} finally {
			try {
				o.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		decompresser.end();
		return output;
	}

	/**
	 * 解压缩
	 * 
	 * @param is
	 *            输入流
	 * @return byte[] 解压缩后的数据
	 */
	public static byte[] decompress(InputStream is) {
		InflaterInputStream iis = new InflaterInputStream(is);
		ByteArrayOutputStream o = new ByteArrayOutputStream(1024);
		try {
			int i = 1024;
			byte[] buf = new byte[i];

			while ((i = iis.read(buf, 0, i)) > 0) {
				o.write(buf, 0, i);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		return o.toByteArray();
	}
}

测试用例代码如下:
Java代码 复制代码  收藏代码
  1. /**  
  2.  * 2009-9-9  
  3.  */  
  4. package org.zlex.commons.io;   
  5.   
  6. import static org.junit.Assert.*;   
  7.   
  8. import java.io.File;   
  9. import java.io.FileInputStream;   
  10. import java.io.FileOutputStream;   
  11.   
  12. import org.junit.Test;   
  13.   
  14. /**  
  15.  * ZLib压缩测试用例  
  16.  *   
  17.  * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>  
  18.  * @version 1.0  
  19.  * @since 1.0  
  20.  */  
  21. public class ZLibUtilsTest {   
  22.   
  23.     @Test  
  24.     public final void testBytes() {   
  25.         System.err.println("字节压缩/解压缩测试");   
  26.         String inputStr = "snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org";   
  27.         System.err.println("输入字符串:\t" + inputStr);   
  28.         byte[] input = inputStr.getBytes();   
  29.         System.err.println("输入字节长度:\t" + input.length);   
  30.   
  31.         byte[] data = ZLibUtils.compress(input);   
  32.         System.err.println("压缩后字节长度:\t" + data.length);   
  33.   
  34.         byte[] output = ZLibUtils.decompress(data);   
  35.         System.err.println("解压缩后字节长度:\t" + output.length);   
  36.         String outputStr = new String(output);   
  37.         System.err.println("输出字符串:\t" + outputStr);   
  38.   
  39.         assertEquals(inputStr, outputStr);   
  40.     }   
  41.   
  42.     @Test  
  43.     public final void testFile() {   
  44.         String filename = "zlib";   
  45.         File file = new File(filename);   
  46.         System.err.println("文件压缩/解压缩测试");   
  47.         String inputStr = "snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org";   
  48.         System.err.println("输入字符串:\t" + inputStr);   
  49.         byte[] input = inputStr.getBytes();   
  50.         System.err.println("输入字节长度:\t" + input.length);   
  51.   
  52.         try {   
  53.   
  54.             FileOutputStream fos = new FileOutputStream(file);   
  55.             ZLibUtils.compress(input, fos);   
  56.             fos.close();   
  57.             System.err.println("压缩后字节长度:\t" + file.length());   
  58.         } catch (Exception e) {   
  59.             fail(e.getMessage());   
  60.         }   
  61.   
  62.         byte[] output = null;   
  63.   
  64.         try {   
  65.             FileInputStream fis = new FileInputStream(file);   
  66.             output = ZLibUtils.decompress(fis);   
  67.             fis.close();   
  68.   
  69.         } catch (Exception e) {   
  70.             fail(e.getMessage());   
  71.         }   
  72.         System.err.println("解压缩后字节长度:\t" + output.length);   
  73.         String outputStr = new String(output);   
  74.         System.err.println("输出字符串:\t" + outputStr);   
  75.   
  76.         assertEquals(inputStr, outputStr);   
  77.     }   
  78. }  
/**
 * 2009-9-9
 */
package org.zlex.commons.io;

import static org.junit.Assert.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.junit.Test;

/**
 * ZLib压缩测试用例
 * 
 * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>
 * @version 1.0
 * @since 1.0
 */
public class ZLibUtilsTest {

	@Test
	public final void testBytes() {
		System.err.println("字节压缩/解压缩测试");
		String inputStr = "snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org";
		System.err.println("输入字符串:\t" + inputStr);
		byte[] input = inputStr.getBytes();
		System.err.println("输入字节长度:\t" + input.length);

		byte[] data = ZLibUtils.compress(input);
		System.err.println("压缩后字节长度:\t" + data.length);

		byte[] output = ZLibUtils.decompress(data);
		System.err.println("解压缩后字节长度:\t" + output.length);
		String outputStr = new String(output);
		System.err.println("输出字符串:\t" + outputStr);

		assertEquals(inputStr, outputStr);
	}

	@Test
	public final void testFile() {
		String filename = "zlib";
		File file = new File(filename);
		System.err.println("文件压缩/解压缩测试");
		String inputStr = "snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org";
		System.err.println("输入字符串:\t" + inputStr);
		byte[] input = inputStr.getBytes();
		System.err.println("输入字节长度:\t" + input.length);

		try {

			FileOutputStream fos = new FileOutputStream(file);
			ZLibUtils.compress(input, fos);
			fos.close();
			System.err.println("压缩后字节长度:\t" + file.length());
		} catch (Exception e) {
			fail(e.getMessage());
		}

		byte[] output = null;

		try {
			FileInputStream fis = new FileInputStream(file);
			output = ZLibUtils.decompress(fis);
			fis.close();

		} catch (Exception e) {
			fail(e.getMessage());
		}
		System.err.println("解压缩后字节长度:\t" + output.length);
		String outputStr = new String(output);
		System.err.println("输出字符串:\t" + outputStr);

		assertEquals(inputStr, outputStr);
	}
}

输入结果
Consloe代码 复制代码  收藏代码
  1. 字节压缩/解压缩测试   
  2. 输入字符串:  snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org   
  3. 输入字节长度: 59  
  4. 压缩后字节长度:    39  
  5. 解压缩后字节长度:   59  
  6. 输出字符串:  snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org   
  7. 文件压缩/解压缩测试   
  8. 输入字符串:  snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org   
  9. 输入字节长度: 59  
  10. 压缩后字节长度:    39  
  11. 解压缩后字节长度:   59  
  12. 输出字符串:  snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org  
字节压缩/解压缩测试
输入字符串:	snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org
输入字节长度:	59
压缩后字节长度:	39
解压缩后字节长度:	59
输出字符串:	snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org
文件压缩/解压缩测试
输入字符串:	snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org
输入字节长度:	59
压缩后字节长度:	39
解压缩后字节长度:	59
输出字符串:	snowolf@zlex.org;dongliang@zlex.org;zlex.dongliang@zlex.org


应该怎么计算呢?原数据长度59字节,压缩后39字节,大约是33%的压缩率!

ZLib压缩对大字节数据压缩,才能反映出压缩效果。
先占个位儿,回头细致整理!

本文转载自:http://snowolf.iteye.com/blog/465433

共有 人打赏支持
村长大神
粉丝 163
博文 876
码字总数 904789
作品 0
杭州
程序员
Android 4.0 external下功能库说明

搞了半天android,竟然对external下的库一无所知?不能容忍! 马上解决: android-mock:编译为java静态库。说明:Android Mock is a framework for mocking interfaces and classes on the...

邓凡平
2012/01/10
0
0
CentOS6.2 java 64 位环境配置

安装编译工具 yum install wget make gcc gcc-c++ zlib-devel openssl openssl-devel pcre-devel gd kernel keyutils patch perl 一、JDK6安装 1、安装JDK 把.bin文件COPY到待安装的指定目录......

枫爱若雪
2013/05/07
0
0
JVM性能优化, Part 5:Java的伸缩性

ImportNew注: JVM性能优化系列文章前4篇由ImportNew翻译(第一篇,第二篇,第三篇, 第四篇)。本文由新浪微博:吴杰 (@WildJay) 投稿至ImportNew。感谢吴杰! 如果你希望分享好的原创文章或...

梁杰_Jack
2014/10/30
0
0
使用Eclipse运行Hadoop 2.x MapReduce程序常见问题

1、 当我们编写好MapReduce程序,点击Run on Hadoop的时候,Eclipse控制台输出如下内容: 这个信息告诉我们没有找到log4j.properties文件。如果没有这个文件,程序运行出错的时候,就没有打印...

东方神剑
2014/11/10
0
0
CentOS 安装JDK跟TOMCAT

最近公司内部服务器采用lamp环境搭建,但又要加上tomcat的访问,而我在搭建环境的时候采用的yum安装,如果大家嫌麻烦也可以去看yum安装apache+php+mysql+tomcat这篇文章,当然我是在yum好lamp环境...

翊骷
2014/09/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

打开eclipse出现an error has occurred see the log file

解决方法: 1,打开eclipse安装目录下的eclipse.ini文件; 2,打开的文本文件最后添加一行 --add-modules=ALL-SYSTEM 3,保存重新打开Eclipse。...

任梁荣
昨天
3
0
搞定Northwind示例数据库,无论哪个版本的SQLServer都受用

Northwind数据库 从这里可以找到突破口: http://social.msdn.microsoft.com/Forums/zh-CN/Vsexpressvb/thread/8490a1c6-9018-40c9-aafb-df9f79d29cde 下面是MSDN: http://msdn2.microsoft......

QQZZFT
昨天
1
0
mysql主从同步,安装配置操作

准备 两台mysql服务,我这里准备了如下: 主库:192.168.176.128 从库:192.168.176.131 如何在Linux上安装mysql服务,请看https://blog.csdn.net/qq_18860653/article/details/80250499 操作...

小致dad
昨天
3
0
一个手机装天下,走遍中国都不怕!

导读 “1200元(人民币,下同),微信支付,可以,你扫我。”来自西非马里共和国的展商Albert拿着手机,和一位买走他手鼓的中国游客用简单的汉语交流着。 近日,“第十四届中俄蒙经贸洽谈暨商品...

问题终结者
昨天
2
0
Redis的“死键”问题

大规模的数据库存储系统中,数据的生命周期管理是很有必要的;从业务角度发现过期数据,数据归档和数据碎片整理等。以MySQL为例,1个运行很久的TB级MySQL实例中,极有可能数百GB的数据,对业...

IT--小哥
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部