文档章节

Java压缩技术(一) ZLib

村长大神
 村长大神
发布于 2014/11/05 13:25
字数 1549
阅读 71
收藏 6
应好友需要,整理一下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

共有 人打赏支持
村长大神
粉丝 162
博文 876
码字总数 904789
作品 0
杭州
程序员
私信 提问
linux C zip 压缩 字符串

项目需要通过zip压缩进行数据传输,linux c为客户端,java为服务端,通过TCP发送,目前已实现java版本的zip压缩解压缩。 现在还需要实现C客户端的zip压缩。 尝试使用zlib的compress,长度不一...

bigbear1007
2016/02/17
864
2
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
CentOS 安装JDK跟TOMCAT

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

翊骷
2014/09/11
0
0
序列化框架比较:kryo & hessian & Protostuff & java

序列化框架性能对比(kryo、hessian、java、protostuff) 简介: 优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Protostuff 速度快,基于protobuf ...

鉴客
2013/03/04
11K
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

没有更多内容

加载失败,请刷新页面

加载更多

eslint rules 规则

'rules': { "comma-dangle": ["error", "never"], //是否允许对象中出现结尾逗号 "no-cond-assign": 2, //条件语句的条件中不允许出现赋值运算符 "no-console": 2, //不允许出现console语句 ...

agenyun
14分钟前
0
0
类型判断时instanceof和equals的不同用法

接口设计时为了避免序列化的麻烦,将接口定义为参数为map<String,String>类型的接口,但是现在调用时需要转换当前的实体Bean为Map,接口接收方再把Map转换为另一个Bean实体。过程中的需要对类...

wangtx
20分钟前
0
0
vue 组件间传值(个人精编)

1.父组件向子组件传值 1⃣️.子组件标签绑定需要传递的参数名2⃣️.子组件页面使用props 接收参数 2.子组件向父组件传值  1⃣️.子组件使用$emit来触发一个自定义事件,并传递一个参...

MrBoyce
31分钟前
1
0
(荷兰)彼得·冯·门施著:博物馆学研究的目的

博物馆学研究的目的 (荷)彼得·冯·门施 尽管诸多关于博物馆学认知目的的不同看法可以被归纳为数个主要群体,但没有一个群体可以被称为“学派”。一般来说,学派是由于博物馆学研究目的的不...

乔老哥
40分钟前
2
0
Vue slot的用法

之前看官方文档,由于自己理解的偏差,不知道slot是干嘛的,看到小标题,使用Slot分发内容,就以为 是要往下派发内容。然后就没有理解插槽的概念。其实说白了,使用slot就是先圈一块地,将来...

peakedness丶
52分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部