编程时,遇到一个字节数组太长,需要压缩存储的需求,想找一个通用的压缩算法,然后搜到了zlib,试了一下,果真是个好东西,分享如下:
Java 参考 Java压缩技术(一) ZLib
Node.js 参考 nodejs 压缩和解压
Java代码:
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();
}
}
public final void testBytes2() {
System.err.println("字节压缩/解压缩测试");
String inputStr = "zjw";
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);
for(byte bt: data) {
System.err.print(Integer.toHexString((int)bt & 0xff) + ",");
}
for(byte bt: input) {
System.out.print(bt + ",");
}
byte[] output = ZLibUtils.decompress(data);
System.err.println("解压缩后字节长度:\t" + output.length);
String outputStr = new String(output);
System.err.println("输出字符串:\t" + outputStr);
}
输出如下:
字节压缩/解压缩测试
输入字符串: zjw
输入字节长度: 3
压缩后字节长度: 11
78,9c,ab,ca,2a,7,0,2,bc,1,5c
解压缩后字节长度: 3
输出字符串: zjw
Node.js
var zlib = require('zlib');
var async = require('async');
function gzip(text){
var buf = new Buffer(text);
var zipRes = null;
async.auto({
zip:function(cb){
zlib.gzip(buf,function(err,res){
zipRes = res;
cb(err,res);
})
},
unzip:['zip',function(cb,res){
var zipRes = res.zip;
zlib.unzip(zipRes,function(err,res){
cb(err,res.toString());
})
}]
},function(err,res){
console.log(zipRes);
console.log(res.unzip);
})
}
function deflate(text){
var buf = new Buffer(text);
var deflateRes = null;
async.auto({
zip:function(cb){
zlib.deflate(buf,function(err,res){
deflateRes = res;
cb(err,res);
})
},
unzip:['zip',function(cb,res){
var zipRes = res.zip;
zlib.unzip(zipRes,function(err,res){
cb(err,res.toString());
})
}]
},function(err,res){
console.log(deflateRes);
console.log(res.unzip);
})
}
gzip('zjw');
deflate('zjw');
node .\compressString.js
<Buffer 1f 8b 08 00 00 00 00 00 00 0a ab ca 2a 07 00 26 53 54 f7 03 00 00 00>
zjw
<Buffer 78 9c ab ca 2a 07 00 02 bc 01 5c>
zjw
可以看到,用deflate压缩的结果与java 是一致的
网友评论