Java对zip格式压缩和解压缩

通过使用java的相关类可以实现对文件或文件夹的压缩,以及对压缩文件的解压。

1.1 ZIP和GZIP的区别

gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格式),它的设计目标是处理单个的文件。gzip在压缩文件中的数据时使用的就是zlib。为了保存与文件属性有关的信息,gzip需要在压缩文件(*.gz)中保存更多的头信息内容,而zlib不用考虑这一点。但gzip只适用于单个文件,所以我们在UNIX/Linux上经常看到的压缩包后缀都是*.tar.gz或*.tgz,也就是先用tar把多个文件打包成单个文件,再用gzip压缩的结果。
     zip只是一种数据结构,跟rar同类型。zip是适用于压缩多个文件的格式(相应的工具有PkZip和WinZip等),因此,zip文件还要进一步包含文件目录结构的信息,比gzip的头信息更多。但需要注意,zip格式可采用多种压缩算法,我们常见的zip文件大多不是用zlib的算法压缩的,其压缩数据的格式与gzip大不一样。

1.2相关类与接口:

Checksum 接口:表示数据校验和的接口,被类Adler32和CRC32实现
Adler32 :使用Alder32算法来计算Checksum数目
CRC32 :使用CRC32算法来计算Checksum数目

CheckedInputStream :InputStream派生类,可得到输入流的校验和Checksum,用于校验数据的完整性
CheckedOutputStream :OutputStream派生类,可得到输出流的校验Checksum, 用于校验数据的完整性

DeflaterOutputStream :压缩类的基类。
ZipOutputStream :DeflaterOutputStream的一个子类,把数据压缩成Zip文件格式
GZIPOutputStream :DeflaterOutputStream的一个子类,把数据压缩成GZip文件格式

InflaterInputStream :解压缩类的基类
ZipInputStream :InflaterInputStream的一个子类,能解压缩Zip格式的数据
GZIPInputStream :InflaterInputStream的一个子类,能解压缩Zip格式的数据

ZipEntry 类:表示 ZIP 文件条目
ZipFile 类:此类用于从 ZIP 文件读取条目

1.3 压缩文件

下面实例我们使用了apache的zip工具包(所在包为ant.jar ),因为java类型自带的不支持中文路径,不过两者使用的方式是一样的,只是apache压缩工具多了设置编码方式的接口,其他基本上是一样的。另外,如果使用org.apache.tools.zip.ZipOutputStream来压缩的话,我们只能使用org.apache.tools.zip.ZipEntry来解压,而不能使用java.util.zip.ZipInputStream来解压读取了,当然apache并未提供ZipInputStream类。

public
static
void compress(String srcFilePath, String destFilePath) {

File src = new File(srcFilePath);

if (!src.exists()) {

throw
new RuntimeException(srcFilePath + "不存在");

}

File zipFile = new File(destFilePath);

try {

FileOutputStream fos = new FileOutputStream(zipFile);

            CheckedOutputStream cos = new CheckedOutputStream(fos, new CRC32());

            ZipOutputStream zos = new ZipOutputStream(cos);

            String baseDir = "";

            compressbyType(src, zos, baseDir);

zos.close();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

private
static
void compressbyType(File src, ZipOutputStream zos,

String baseDir) {

if (!src.exists())

return;

System.out.println("压缩" + baseDir + src.getName());

if (src.isFile()) {

compressFile(src, zos, baseDir);

} else
if (src.isDirectory()) {

compressDir(src, zos, baseDir);

}

}

/**

* 压缩文件

*

*/

private
static
void compressFile(File file, ZipOutputStream zos,

String baseDir) {

if (!file.exists())

return;

try {

BufferedInputStream bis = new BufferedInputStream(

                    new FileInputStream(file));

            ZipEntry entry = new ZipEntry(baseDir + file.getName());

            zos.putNextEntry(entry);

            int count;

            byte[] buf = new byte[BUFSIZE];

            while ((count = bis.read(buf)) != -1) {

                zos.write(buf, 0, count);

            }

bis.close();

} catch (Exception e) {

// TODO: handle exception

}

}

/**

* 压缩文件夹

*

*/

private
static
void compressDir(File dir, ZipOutputStream zos,

String baseDir) {

if (!dir.exists())

return;

File[] files = dir.listFiles();

if(files.length == 0){

            try {

                zos.putNextEntry(new ZipEntry(baseDir + dir.getName()

                        + File.separator));

            } catch (IOException e) {

                e.printStackTrace();

            }

            

        }

for (File file : files) {

compressbyType(file, zos, baseDir + dir.getName() + File.separator);

}

}

总结步骤:

  1. 创建压缩到的文件File zipFile = new File(destFilePath);
  2. 根据zipFile生成ZipOutputStream用于写入即将被压缩的文件

    FileOutputStream fos = new FileOutputStream(zipFile);

    CheckedOutputStream cos = new                                      CheckedOutputStream(fos, new CRC32());

    ZipOutputStream zos = new ZipOutputStream(cos);

  3. 循环遍历源文件,首先需要创建ZipEntry用于标记压缩文件中含有的条目

    ZipEntry entry = new ZipEntry(baseDir + file.getName());

    然后将条目增加到ZipOutputStream中,

    zos.putNextEntry(entry);

    最后再调用要写入条目对应文件的输入流读取文件内容写入到压缩文件中。

    BufferedInputStream bis = new BufferedInputStream(

            new FileInputStream(file));

            ZipEntry entry = new ZipEntry(baseDir + file.getName());

            zos.putNextEntry(entry);

            int count;

            byte[] buf = new byte[BUFSIZE];

            while ((count = bis.read(buf)) != -1) {

                zos.write(buf, 0, count);

            }

    注意:如果是空目录直接zos.putNextEntry(new ZipEntry(baseDir +     dir.getName()+ File.separator))并不用写入文件内容,其中最主要的涉及到目录的压缩的,就是这一句话  out.putNextEntry(new ZipEntry(base + "/")); //放入一级目录 (防止空目录被丢弃)

    1.4 解压zip文件

    public
    static
    void decompress(String srcPath, String dest) throws Exception {

    File file = new File(srcPath);

    if (!file.exists()) {

    throw
    new RuntimeException(srcPath + "所指文件不存在");

    }

    ZipFile zf = new ZipFile(file);

    Enumeration
    entries = zf.getEntries();

    ZipEntry
    entry = null;

    while (entries.hasMoreElements()) {

    entry = (ZipEntry) entries.nextElement();

    System.out.println("解压" + entry.getName());

    if (entry.isDirectory()) {

    String dirPath = dest + File.separator + entry.getName();

    File dir = new File(dirPath);

    dir.mkdirs();

    } else {

    // 表示文件

    File f = new File(dest + File.separator + entry.getName());

    if (!f.exists()) {

    String dirs = FileUtils.getParentPath(f);

    File parentDir = new File(dirs);

    parentDir.mkdirs();

    }

    f.createNewFile();

    // 将压缩文件内容写入到这个文件中

    InputStream is = zf.getInputStream(entry);

    FileOutputStream fos = new FileOutputStream(f);

    int
    count;

    byte[] buf = new
    byte[8192];

    while ((count = is.read(buf)) != -1) {

    fos.write(buf, 0, count);

    }

    is.close();

    fos.close();

    }

    }

    }

Java对zip格式压缩和解压缩的更多相关文章

  1. Java用ZIP格式压缩和解压缩文件

    转载:java jdk实例宝典 感觉讲的非常好就转载在这保存! java.util.zip包实现了Zip格式相关的类库,使用格式zip格式压缩和解压缩文件的时候,须要导入该包. 使用zipoutput ...

  2. Java 的zip压缩和解压缩

    Java 的zip压缩和解压缩 好久没有来这写东西了,今天中秋节,有个东西想拿出来分享,一来是工作中遇到的问题,一来是和csdn问候一下,下面就分享一个Java中的zip压缩技术,代码实现比较简单,代 ...

  3. [Java 基础] 使用java.util.zip包压缩和解压缩文件

    reference :  http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...

  4. java采用zip方式实现String的压缩和解压缩CompressStringUtil类

    CompressStringUtil类:不多说,直接贴代码: /** * 压缩 * * @param paramString * @return */ public static final byte ...

  5. Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)

    Java ZIP压缩和解压缩文件(解决中文文件名乱码问题) 学习了:http://www.tuicool.com/articles/V7BBvy 引用原文: JDK中自带的ZipOutputStrea ...

  6. 使用commons-compress操作zip文件(压缩和解压缩)

    http://www.cnblogs.com/luxh/archive/2012/06/28/2568758.html Apache Commons Compress是一个压缩.解压缩文件的类库. 可 ...

  7. Linux常用命令学习3---(文件的压缩和解压缩命令zip unzip tar、关机和重启命令shutdown reboot……)

    1.压缩和解压缩命令    常用压缩格式:.zip..gz..bz2..tar.gz..tar.bz2..rar .zip格式压缩和解压缩命令        zip 压缩文件名 源文件:压缩文件   ...

  8. IO操作之使用zip包压缩和解压缩文件

    转自:http://www.cdtarena.com/java.html​​Java API中的import java.util.zip.*;包下包含了Java对于压缩文件的所有相关操作. 我们可以使 ...

  9. java工具类——java将一串数据按照gzip方式压缩和解压缩

    我要整理在工作中用到的工具类分享出来,也方便自己以后查阅使用,这些工具类都是我自己实际工作中使用的 import java.io.ByteArrayInputStream; import java.i ...

随机推荐

  1. backbone.js 学习笔记

    Backbone.Model 模型.相当于表定义,定义一个表当中有的列 defaults:设置属性的默认值 initialize():初始化函数 get(key):获取属性值 set(data):设置 ...

  2. 初学Ionic

    官网 https://ionicframework.com/ 如连接所示,可跳转到该前端框架的官网,在这里提供了两种方式可供大家学习: Code with the CLI Design with lo ...

  3. java学习笔记—第三方数据库连接池包1(29)

    第一步:导入dbcp包 第二步:通过核心类连接数据 BasicDataSource它是javax.sql.DataSrouce的子类. 一个工具类:BasicDataSourceFactory. 手工 ...

  4. Jmeter_RabbitMQ性能测试

    [前言] RabbitMQ消息的传递并非使用HTTP协议,而是AMQP协议,因此除非开发暴露一个HTTP请求接口出来,否则无法直接使用HTTP请求发送json串数据,实现数据publish到MQ中. ...

  5. Word2007文档中怎么输入上标下标

    1.Word中输出Z = X2 + Y2 此公式流程: 首先在Word中写入:Z = X2 + Y2: 方法1:选中X后面的2,再按组合键“Ctrl+Shift+加号键”即可,如此操作Y后面的2即可.

  6. cnpm安装过程中提示optional install error: Package require os(darwin) not compatible with your platform(win32)解决方法

    运行cnpm install后,出现 虽然提示不适合Windows,但是问题好像是sass loader出问题的.所以只要执行下面命令即可: 方案一: cnpm rebuild node-sass # ...

  7. python3+requests:post请求四种传送正文方式(详解)

    前言:post请求我在python接口自动化2-发送post请求详解(二)已经讲过一部分了,主要是发送一些较长的数据,还有就是数据比较安全等,可以参考Get,Post请求方式经典详解进行学习一下. 我 ...

  8. ansible api2.0 多进程执行不同的playbook

    自动化运维工具:ansible 多进程调用ansible api的应用场景:   应用系统检查 一个应用系统可能具有20—50台服务器的集群,初步的系统层面检查可以用一个统一的playbook来检查, ...

  9. MySQL数据库管理

    好记性不如烂笔头 1.MySQL启动基本原理 /etc/init.d/mysqld 是一个shell启动脚本,启动后会调用mysqld_safe脚本,最后调用的是mysqld主程序启动mysql. 单 ...

  10. Solr7.4的学习与使用

    学习的原因: 17年的时候有学习使用过lucene和solr,但是后来也遗忘了,最近公司有个项目需要使用到全文检索,正好也顺便跟着学习一下,使用的版本是Solr7.4的,下载地址:http://arc ...