程序员一代码搬运工
【Java学习心得和Java学习技术个人总结】

GZIP java 压缩技术

d000baa1cd11728b2180e728cafcc3cec3fd2c0e

GZIP常常用在linxu环境下,是一种非常简单的压缩算法。在Java实现API中,它仅仅包含两个实现类:GZIPInputStream和GZIPOutputStream。
GZIPOutputStream类用于压缩
GZIPInputStream类用于解压缩

先说压缩实现,GZIPOutputStream只有一个方法用于压缩,就是带定长的write方法。简单调用如下文所示:

 

/** 
 * 数据压缩 
 *  
 * @param is 
 * @param os 
 * @throws Exception 
 */  
public static void compress(InputStream is, OutputStream os)  
        throws Exception {  
  
    GZIPOutputStream gos = new GZIPOutputStream(os);  
  
    int count;  
    byte data[] = new byte[BUFFER];  
    while ((count = is.read(data, 0, BUFFER)) != -1) {  
        gos.write(data, 0, count);  
    }  
  
    gos.finish();  
  
    gos.flush();  
    gos.close();  
}

记得完成操作后,调用finish方法和flush方法!

核心的压缩实现就这么多!

对于解压缩,GZIPInputStream也对应GZIPOutputStream提供了一个带定长的read方法。简单调用如下文所示:

 

/** 
 * 数据解压缩 
 *  
 * @param is 
 * @param os 
 * @throws Exception 
 */  
public static void decompress(InputStream is, OutputStream os)  
        throws Exception {  
  
    GZIPInputStream gis = new GZIPInputStream(is);  
  
    int count;  
    byte data[] = new byte[BUFFER];  
    while ((count = gis.read(data, 0, BUFFER)) != -1) {  
        os.write(data, 0, count);  
    }  
  
    gis.close();  
}  

就这么简单! 核心内容完毕!

顺便补充一下,在liunx下操作gzip命令

gzip file用于压缩,如gzip a.txt将得到文件a.txt.gz同时删除文件a.txt!。
gzip -d file.gz用于解压缩,如gzip -d a.txt.gz将得到文件a.txt同时删除文件a.txt.gz!。

根据这些特性,我补充了相应的文件操作实现,详见下文!

/** 
 * 2010-4-13 
 */  
package org.zlex.commons.io;  
  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.util.zip.GZIPInputStream;  
import java.util.zip.GZIPOutputStream;  
  
/** 
 * GZIP工具 
 *  
 * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a> 
 * @since 1.0 
 */  
public abstract class GZipUtils {  
  
    public static final int BUFFER = 1024;  
    public static final String EXT = ".gz";  
  
    /** 
     * 数据压缩 
     *  
     * @param data 
     * @return 
     * @throws Exception 
     */  
    public static byte[] compress(byte[] data) throws Exception {  
        ByteArrayInputStream bais = new ByteArrayInputStream(data);  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  
        // 压缩  
        compress(bais, baos);  
  
        byte[] output = baos.toByteArray();  
  
        baos.flush();  
        baos.close();  
  
        bais.close();  
  
        return output;  
    }  
  
    /** 
     * 文件压缩 
     *  
     * @param file 
     * @throws Exception 
     */  
    public static void compress(File file) throws Exception {  
        compress(file, true);  
    }  
  
    /** 
     * 文件压缩 
     *  
     * @param file 
     * @param delete 
     *            是否删除原始文件 
     * @throws Exception 
     */  
    public static void compress(File file, boolean delete) throws Exception {  
        FileInputStream fis = new FileInputStream(file);  
        FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);  
  
        compress(fis, fos);  
  
        fis.close();  
        fos.flush();  
        fos.close();  
  
        if (delete) {  
            file.delete();  
        }  
    }  
  
    /** 
     * 数据压缩 
     *  
     * @param is 
     * @param os 
     * @throws Exception 
     */  
    public static void compress(InputStream is, OutputStream os)  
            throws Exception {  
  
        GZIPOutputStream gos = new GZIPOutputStream(os);  
  
        int count;  
        byte data[] = new byte[BUFFER];  
        while ((count = is.read(data, 0, BUFFER)) != -1) {  
            gos.write(data, 0, count);  
        }  
  
        gos.finish();  
  
        gos.flush();  
        gos.close();  
    }  
  
    /** 
     * 文件压缩 
     *  
     * @param path 
     * @throws Exception 
     */  
    public static void compress(String path) throws Exception {  
        compress(path, true);  
    }  
  
    /** 
     * 文件压缩 
     *  
     * @param path 
     * @param delete 
     *            是否删除原始文件 
     * @throws Exception 
     */  
    public static void compress(String path, boolean delete) throws Exception {  
        File file = new File(path);  
        compress(file, delete);  
    }  
  
    /** 
     * 数据解压缩 
     *  
     * @param data 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decompress(byte[] data) throws Exception {  
        ByteArrayInputStream bais = new ByteArrayInputStream(data);  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  
        // 解压缩  
  
        decompress(bais, baos);  
  
        data = baos.toByteArray();  
  
        baos.flush();  
        baos.close();  
  
        bais.close();  
  
        return data;  
    }  
  
    /** 
     * 文件解压缩 
     *  
     * @param file 
     * @throws Exception 
     */  
    public static void decompress(File file) throws Exception {  
        decompress(file, true);  
    }  
  
    /** 
     * 文件解压缩 
     *  
     * @param file 
     * @param delete 
     *            是否删除原始文件 
     * @throws Exception 
     */  
    public static void decompress(File file, boolean delete) throws Exception {  
        FileInputStream fis = new FileInputStream(file);  
        FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT,  
                ""));  
        decompress(fis, fos);  
        fis.close();  
        fos.flush();  
        fos.close();  
  
        if (delete) {  
            file.delete();  
        }  
    }  
  
    /** 
     * 数据解压缩 
     *  
     * @param is 
     * @param os 
     * @throws Exception 
     */  
    public static void decompress(InputStream is, OutputStream os)  
            throws Exception {  
  
        GZIPInputStream gis = new GZIPInputStream(is);  
  
        int count;  
        byte data[] = new byte[BUFFER];  
        while ((count = gis.read(data, 0, BUFFER)) != -1) {  
            os.write(data, 0, count);  
        }  
  
        gis.close();  
    }  
  
    /** 
     * 文件解压缩 
     *  
     * @param path 
     * @throws Exception 
     */  
    public static void decompress(String path) throws Exception {  
        decompress(path, true);  
    }  
  
    /** 
     * 文件解压缩 
     *  
     * @param path 
     * @param delete 
     *            是否删除原始文件 
     * @throws Exception 
     */  
    public static void decompress(String path, boolean delete) throws Exception {  
        File file = new File(path);  
        decompress(file, delete);  
    }  
  
}

罗嗦了半天,到底行不行?
来个测试用例,测试用例如下所示:

/** 
 * 2010-4-13 
 */  
package org.zlex.commons.compress.compress;  
  
import static org.junit.Assert.assertEquals;  
  
import java.io.DataInputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
  
import org.junit.Test;  
  
/** 
 * @author <a href="mailto:zlex.dongliang@gmail.com">梁栋</a> 
 * @since 1.0 
 */  
public class GZipUtilsTest {  
  
    private String inputStr = "zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org";  
  
    @Test  
    public final void testDataCompress() throws Exception {  
  
        System.err.println("原文:\t" + inputStr);  
  
        byte[] input = inputStr.getBytes();  
        System.err.println("长度:\t" + input.length);  
  
        byte[] data = GZipUtils.compress(input);  
        System.err.println("压缩后:\t");  
        System.err.println("长度:\t" + data.length);  
  
        byte[] output = GZipUtils.decompress(data);  
        String outputStr = new String(output);  
        System.err.println("解压缩后:\t" + outputStr);  
        System.err.println("长度:\t" + output.length);  
  
        assertEquals(inputStr, outputStr);  
  
    }  
  
    @Test  
    public final void testFileCompress() throws Exception {  
  
        FileOutputStream fos = new FileOutputStream("d:/f.txt");  
  
        fos.write(inputStr.getBytes());  
        fos.flush();  
        fos.close();  
  
        GZipUtils.compress("d:/f.txt", false);  
  
        GZipUtils.decompress("d:/f.txt.gz", false);  
  
        File file = new File("d:/f.txt");  
  
        FileInputStream fis = new FileInputStream(file);  
  
        DataInputStream dis = new DataInputStream(fis);  
  
        byte[] data = new byte[(int) file.length()];  
        dis.readFully(data);  
  
        fis.close();  
  
        String outputStr = new String(data);  
        assertEquals(inputStr, outputStr);  
    }  
}

结果如何?
先看testDataCompress()方法控制台输出结果。
控制台输出如下:

原文:	zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org 
长度:	52 
压缩后:	
长度:	45 
解压缩后:	zlex@zlex.org,snowolf@zlex.org,zlex.snowolf@zlex.org 
长度:	52

这里使用英文字符做测试,当输入字符串的字节数大于50左右时,压缩效果明显;如果这里使用中文压缩,可能当压缩上千字节时方能体现出压缩效果!
对于文件操作,朋友们可以自行实验,我代码里的实现是按照gzip命令来的!
举例来说:
压缩时,将文件a.txt压缩为a.txt.gz,同时删除文件a.txt。
解压缩时,将文件a.txt.gz解压缩为a.txt,同时删除文件a.txt.gz。

注意执行testFileCompress方法,查看产生的文件! 你大可以放到linux上去做验证!

commons也提供了GZIP算法的实现,甚至更多种压缩算法(tar、bzip2等)的实现,有机会我将继续整理!

d000baa1cd11728b2180e728cafcc3cec3fd2c0e

来自 大神  http://snowolf.iteye.com/blog/643010

好多的压缩技术。。

赞(0)
未经允许不得转载:程序员一代码搬运工 » GZIP java 压缩技术
分享到: 更多 (0)