Java 解压缩各种格式

一. Gzip解压缩

工具类:

package com.mazaiting;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipUtil {
    /**utf-8编码*/
    public static final String GZIP_ENCODE_UTF_8 = "UTF-8";
    /**iso-8859-1编码*/
    public static final String GZIP_ENCODE_ISO_8859_1 = "ISO-8859-1";
    
    
    /**
     * "utf-8"编码压缩
     * @param string 要压缩的字符串
     * @return 字节数组
     */
    public static byte[] compress(String string) {
        return compress(string, GZIP_ENCODE_UTF_8);
    }

    /**
     * 指定编码压缩
     * @param string 要压缩的字符串
     * @param encoding 编码
     * @return 字节数组
     */
    public static byte[] compress(String string, String encoding) {
        // 判断是否为空
        if (null == string || string.length() == 0) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutputStream;
        try {
            gzipOutputStream = new GZIPOutputStream(baos);
            gzipOutputStream.write(string.getBytes(encoding));
            gzipOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }

    /**
     * 解压为字节数组
     * @param bytes 要解压的字节数组
     * @return 字节数组
     */
    public static byte[] uncompress(byte[] bytes) {
        if (null == bytes || bytes.length == 0) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        GZIPInputStream unGzip;
        try {
            unGzip = new GZIPInputStream(bais);
            byte[] buffer = new byte[256];
            int n;
            while ((n = unGzip.read(buffer)) >= 0) {
                baos.write(buffer, 0, n);               
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }

    /**
     * "utf-8"编码解压
     * @param bytes 要解压的字节数组
     * @return 字节数组
     */
    public static String uncompressToString(byte[] bytes) {
        return uncompressToString(bytes, GZIP_ENCODE_UTF_8);
    }

    /**
     * 指定编码解压
     * @param string 要压缩的字符串
     * @param encoding 编码
     * @return 字节数组
     */
    public static String uncompressToString(byte[] bytes, String encoding) {
        if (null == bytes || bytes.length == 0) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        GZIPInputStream unGzip;
        try {
            unGzip = new GZIPInputStream(bais);
            byte[] buffer = new byte[256];
            int n;
            while ((n = unGzip.read(buffer)) >= 0) {
                baos.write(buffer, 0, n);               
            }
            return baos.toString(encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

具体使用:

package com.mazaiting;

public class Test {
    public static void main(String[] args) {
        String string = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        System.out.println("字符串长度: " + string.length());
        System.out.println("压缩后: " + GzipUtil.compress(string).length);
        System.out.println("解压后: " + GzipUtil.uncompress(GzipUtil.compress(string)).length);
        System.out.println("解压后字符串长度: " + GzipUtil.uncompressToString(GzipUtil.compress(string)).length());
    }
}

二、Zip解压缩

文中所需工具类Java 文件遍历

  1. 工具类
 
/**
 * Zip格式数据操作类
 * @author mazaiting
 */
public class ZipUtil {
    /**缓冲字节--1M*/
    private static final int BUFF_SIZE = 1024 * 1024;
    
    /**
     * 批量压缩文件(文件夹)
     * @param resFileList 要压缩的文件(夹)列表
     * @param zipFile 生成的压缩文件
     * @throws IOException 当压缩过程出错时抛出
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile) throws IOException {
        ZipOutputStream zipOut = new ZipOutputStream(
                new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipOut, "");
        }
        zipOut.close();
    }
    
    /**
     * 批量压缩文件(文件夹)
     * @param resFileList 要压缩的文件(夹)列表
     * @param zipFile 生成的压缩文件
     * @param comment 压缩文件的注释
     * @throws IOException 当压缩过程出错时抛出 
     */ 
    public static void zipFiles(Collection<File> resFileList, File zipFile, String comment) throws IOException {
        ZipOutputStream zipOut = new ZipOutputStream(
                new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipOut, "");
        }
        zipOut.setComment(comment);
        zipOut.close();
    }
    
    /**
     * 解压缩一个文件
     * @param zipFile 压缩文件
     * @param folderPath 解压缩的目标目录
     * @throws IOException 
     * @throws ZipException 
     */
    public static void upZipFile(File zipFile, String folderPath) throws ZipException, IOException {
        // 根据路径创建一个文件
        File desDir = new File(folderPath);
        // 判断文件是否存在,如果不存在则创建
        if (!desDir.exists()) {
            desDir.mkdirs();
        }
        // 创建一个压缩文件
        ZipFile zFile = new ZipFile(zipFile);
        // 循环遍历
        for (Enumeration<?> entries = zFile.entries(); entries.hasMoreElements(); ){
            ZipEntry entry = (ZipEntry) entries.nextElement();
            InputStream in = zFile.getInputStream(entry);
            String str = folderPath + File.separator + entry.getName();
            str = new String(str.getBytes("8859_1"), "GB2312");
            File desFile = new File(str);
            // 判断文件是否存在
            if (!desFile.exists()) {
                File fileParentDir = desFile.getParentFile();
                // 判断父文件夹是否存在
                if (!fileParentDir.exists()) {
                    fileParentDir.mkdirs();
                }
                // 创建新文件
                desFile.createNewFile();
            }
            OutputStream out = new FileOutputStream(desFile);
            byte[] buffer = new byte[BUFF_SIZE];
            int realLength;
            while ((realLength = in.read(buffer)) >0) {
                out.write(buffer, 0, realLength);
            }
            in.close();
            out.close();
        }
        
    }
    
    /**
     * 解压文件名包含传入文字的文件
     * @param zipFile 压缩文件
     * @param folderPath 目标文件夹
     * @param nameContains 传入的文件匹配名
     * @throws ZipException 压缩格式有误时抛出
     * @throws IOException IO错误时抛出
     */
    public static ArrayList<File> upZipSelectedFile(File zipFile, String folderPath,
            String nameContains) throws ZipException, IOException {
        ArrayList<File> fileList = new ArrayList<File>();
 
        File desDir = new File(folderPath);
        if (!desDir.exists()) {
            desDir.mkdir();
        }
 
        ZipFile zf = new ZipFile(zipFile);
        for (Enumeration<?> entries = zf.entries(); entries.hasMoreElements();) {
            ZipEntry entry = ((ZipEntry)entries.nextElement());
            if (entry.getName().contains(nameContains)) {
                InputStream in = zf.getInputStream(entry);
                String str = folderPath + File.separator + entry.getName();
                str = new String(str.getBytes("8859_1"), "GB2312");
                // str.getBytes("GB2312"),"8859_1" 输出
                // str.getBytes("8859_1"),"GB2312" 输入
                File desFile = new File(str);
                if (!desFile.exists()) {
                    File fileParentDir = desFile.getParentFile();
                    if (!fileParentDir.exists()) {
                        fileParentDir.mkdirs();
                    }
                    desFile.createNewFile();
                }
                OutputStream out = new FileOutputStream(desFile);
                byte buffer[] = new byte[BUFF_SIZE];
                int realLength;
                while ((realLength = in.read(buffer)) > 0) {
                    out.write(buffer, 0, realLength);
                }
                in.close();
                out.close();
                fileList.add(desFile);
            }
        }
        return fileList;
    }
    

    /**
     * 压缩文件
     * @param resFile 需要压缩的文件(夹)
     * @param zipOut 压缩的目的文件
     * @param rootPath 压缩的文件路径
     * @throws IOException 
     */
    private static void zipFile(File resFile, ZipOutputStream zipOut, String rootPath) throws IOException {
        // 判断文件路径长度是否大于0, 大于0时string为"/", 等于0时为""
        String string = rootPath.trim().length() == 0 ? "" : File.separator;
        // 压缩文件生成的路径
        rootPath = rootPath + string + resFile.getName();
        // 路径转码
        rootPath = new String(rootPath.getBytes("8859_1"), "GB2312");
        // 判断压缩的是否是路径
        if (resFile.isDirectory()) {
            // 获取当前路径下的所有文件
            File[] listFiles = resFile.listFiles();
            for (File file : listFiles) {
                zipFile(file, zipOut, rootPath);
            }
        } else {
            byte[] buffer = new byte[BUFF_SIZE];
            BufferedInputStream in = new BufferedInputStream(
                    new FileInputStream(resFile), BUFF_SIZE);
            zipOut.putNextEntry(new ZipEntry(rootPath));
            int realLength;
            while ((realLength = in.read(buffer)) != -1) {
                zipOut.write(buffer, 0, realLength);                
            }
            in.close();
            zipOut.flush();
            zipOut.closeEntry();
        }
    }
    
    /**
     * 获得压缩文件内文件列表
     * @param zipFile 压缩文件
     * @return 压缩文件内文件名称
     * @throws IOException 
     * @throws ZipException 
     */
    public static ArrayList<String> getEntriesNames(File zipFile) throws ZipException, IOException {
        ArrayList<String> entryNames = new ArrayList<>();
        Enumeration<?> entries = getEntriesEnumeration(zipFile);
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            entryNames.add(new String(
                    getEntryName(entry).getBytes("GB2312"), "8859_1"));
        }
        return entryNames;
    }

    /**
     * 获得压缩文件对象的名称
     * @param entry 压缩文件对象
     * @return 压缩文件对象的名称
     * @throws UnsupportedEncodingException 
     */
    private static String getEntryName(ZipEntry entry) throws UnsupportedEncodingException {
        return new String(entry.getName().getBytes("GB2312"), "8859_1");
    }

    /**
     * 取得压缩文件对象的注释
     * @param entry 压缩文件对象
     * @return 压缩文件对象的注释
     * @throws UnsupportedEncodingException 
     */
    public static String getEntryComment(ZipEntry entry) throws UnsupportedEncodingException {
        return new String(entry.getComment().getBytes("GB2312"), "8859_1");
    }
    
    /**
     * 获得压缩文件内压缩文件对象以取得其属性
     * @param zipFile 压缩文件
     * @return 返回一个压缩文件列表
     * @throws IOException 
     * @throws ZipException 
     */
    private static Enumeration<?> getEntriesEnumeration(File zipFile) throws ZipException, IOException {
        ZipFile zf = new ZipFile(zipFile);
        return zf.entries();
    }   
}

  1. 使用
public class Test {
    public static void main(String[] args) throws IOException {
        ArrayList<File> listFiles = DirTraversal.listFiles("E:\\web");
        for (File file : listFiles) {
            System.out.println(file.getAbsolutePath());
        }
        

        File zipFile = new File("E:\\web\\file.zip");
        ZipUtil.zipFiles(listFiles, zipFile);
        
//      File zipFile = new File("E:\\web\\file.zip");
//      ZipUtil.zipFiles(listFiles, zipFile, "Hello");
        
//      File zipFile = new File("E:\\web\\file.zip");
//      ZipUtil.upZipFile(zipFile, "E:\\web");
        
    }
}

三、Apache Commons Compress解压缩

支持ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200, bzip2, 7z, arj, lzma, snappy, DEFLATE, lz4, Brotli and Z files格式。


/**
 * BZip2解压缩工具类
 * @author mazaiting
 */
public class BZip2Util {
    /**缓冲字节*/
    public static final int BUFFER = 1024;
    /**后缀名*/
    public static final String EXT = ".bz2";
    
    /**
     * 数据压缩
     * @param data 数据字节
     * @return
     * @throws IOException 
     */
    public static byte[] compress(byte[] data) throws IOException {
        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 文件
     * @param delete 是否删除原文件
     * @throws IOException 
     */
    public static void compress(File file, boolean delete) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);
        
        compress(fis, fos);
        
        fos.flush();
        
        fos.close();
        fis.close();
        
        if (delete) {
            file.delete();
        }
    }

    /**
     * 数据压缩
     * @param is 输入流 
     * @param os 输出流
     * @throws IOException 
     */
    private static void compress(InputStream is, OutputStream os) throws IOException {
        BZip2CompressorOutputStream bcos = new BZip2CompressorOutputStream(os);
        
        int count;
        byte data[] = new byte[BUFFER];
        
        while((count = is.read(data, 0, BUFFER)) != -1){
            bcos.write(data, 0, count);
        }
        
        bcos.finish();
        
        bcos.flush();
        bcos.close();       
    }
    
    /**
     * 文件压缩
     * @param path 文件路径
     * @param delete 是否删除原文件
     * @throws IOException 
     */
    public static void compress(String path, boolean delete) throws IOException{
        File file = new File(path);
        compress(file, delete);
    }
    
    /**
     * 数据解压缩
     * @param data 数据
     * @return 
     * @throws IOException 
     */
    public static byte[] deCompress(byte[] data) throws IOException{
        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 文件
     * @param delete 是否删除源文件
     * @throws IOException 
     */
    public static void deCompress(File file, boolean delete) throws IOException{
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT, ""));
        
        deCompress(fis, fos);
        
        fos.flush();
        fos.close();
        fis.close();
        
        if (delete) {
            file.delete();
        }
    }
    
    /**
     * 解压缩
     * @param is 输入流
     * @param os 输出流
     * @throws IOException 
     */
    private static void deCompress(InputStream is, OutputStream os) throws IOException {
        BZip2CompressorInputStream bcis = new BZip2CompressorInputStream(is);
        
        int count;
        byte data[] = new byte[BUFFER];
        
        while((count = bcis.read(data, 0, BUFFER)) != -1){
            os.write(data, 0, count);
        }
        
        bcis.close();
    }
    
    /**
     * 文件解压缩
     * @param path 文件路径
     * @param delete 是否删除源文件
     * @throws IOException 
     */
    public static void deCompress(String path, boolean delete) throws IOException{
        File file = new File(path);
        deCompress(file, delete);
    }
        
}   

上面为BZip2解压缩代码, 若是想用其他格式的解压缩,可以将代码中的BZip2CompressorInputStream 和BZip2CompressorOutputStream相对应的替换就可以。

  • .ar对应ArArchiveInputStream和ArArchiveOutputStream
  • .cpio对应CpioArchiveInputStream和CpioArchiveOutputStream
  • .dump对应DumpArchiveInputStream
  • .tar对应TarArchiveInputStream和TarArchiveOutputStream
  • .zip对应ZipArchiveInputStream和ZipArchiveOutputStream
  • .gzip对应GzipCompressorInputStream和GzipCompressorOutputStream
  • .xz对应XZCompressorInputStream和XZCompressorOutputStream
  • .pack200对应Pack200CompressorInputStream和Pack200CompressorOutputStream
  • .bzip2对应BZip2CompressorInputStream和BZip2CompressorOutputStream
  • .7z对应SevenZFile和SevenZOutputFile
  • .arj对应ArjArchiveInputStream
  • .lzma对应LZMACompressorInputStream和LZMACompressorOutputStream
  • .snappy对应SnappyCompressorInputStream和SnappyCompressorOutputStream
  • .deflate对应DeflateCompressorInputStream和DeflateCompressorOutputStream
  • .lz4对应BlockLZ4CompressorInputStream和BlockLZ4CompressorOutputStream
  • .brotli 对应BrotliCompressorInputStream
  • .z对应ZCompressorInputStream
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • 为什么要整理一下Linux下的打包和压缩工具呢?原因很简单,因为遇到问题了:游戏服务器可执行文件、配置和各种资源文...
    davidpp阅读 9,924评论 0 18
  • 一、linux中常见的压缩包文件格式 文件后缀名 说明 *.zip ...
    bewhyy阅读 746评论 0 0
  • 一、概念讲解 Windows 上最常见的是三种以.zip,.rar,.7z 为后缀的压缩文件,而在 Linux 上...
    睡不醒醒阅读 898评论 0 0
  • 第一次写“简书”,深夜了,刚结束一群人的狂欢,然后带着一身的孤单感回到家,我好想你,在今天第一次对你发脾气之后,可...
    Amaya小姐姐阅读 250评论 0 0
  • 文/尕伱哈 不知道你有没有遇到过这样的事情,刚读完一本不错的书,心情也很愉快,非常想与人分享,然而却表达不出甚至忘...
    尕伱哈阅读 452评论 2 8