java解压工具_Java_压缩与解压工具类

本文档详细介绍了如何使用Java的ZipOutputStream和ZipInputStream类进行文件及文件夹的压缩和解压缩操作,包括处理空文件夹的情况。代码示例展示了如何创建ZipOutputStream来压缩数据,以及如何通过ZipInputStream解压缩文件到指定目录。
摘要由CSDN通过智能技术生成

package com.raise.raisestudy.zip;

import android.text.TextUtils;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.ByteArrayOutputStream;

import java.io.Closeable;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.zip.CRC32;

import java.util.zip.CheckedOutputStream;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;

import java.util.zip.ZipOutputStream;

/**

* zip文件加压解压原理如下

* compress@see {@link ZipOutputStream}

* *

 
 

* OutputStream os = ...

* ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(os));

* try {

* for (int i = 0; i < fileCount; ++i) {

* String filename = ...

* byte[] bytes = ...

* ZipEntry entry = new ZipEntry(filename);

* zos.putNextEntry(entry);

* zos.write(bytes);

* zos.closeEntry();

* }

* } finally {

* zos.close();

* }

*

* decompress@see {@link ZipInputStream}

*

 
 

* InputStream is = ...

* ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));

* try {

* ZipEntry ze;

* while ((ze = zis.getNextEntry()) != null) {

* ByteArrayOutputStream baos = new ByteArrayOutputStream();

* byte[] buffer = new byte[1024];

* int count;

* while ((count = zis.read(buffer)) != -1) {

* baos.write(buffer, 0, count);

* }

* String filename = ze.getName();

* byte[] bytes = baos.toByteArray();

* // do something with 'filename' and 'bytes'...

* }

* } finally {

* zis.close();

* }

*

* 支持空文件夹加压解压

* Created by raise.yang on 16/08/09.

*/

public class ZipUtil {

private static final String TAG = "ZipUtil";

/**

* 解压文件到指定文件夹

*

*@param zip 源文件

*@param destPath 目标文件夹路径

*@throws Exception 解压失败

*/

public static void decompress(String zip, String destPath) throws Exception {

//参数检查

if (TextUtils.isEmpty(zip) || TextUtils.isEmpty(destPath)) {

throw new IllegalArgumentException("zip or destPath is illegal");

}

File zipFile = new File(zip);

if (!zipFile.exists()) {

throw new FileNotFoundException("zip file is not exists");

}

File destFolder = new File(destPath);

if (!destFolder.exists()) {

if (!destFolder.mkdirs()) {

throw new FileNotFoundException("destPath mkdirs is failed");

}

}

ZipInputStream zis = null;

BufferedOutputStream bos = null;

try {

zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zip)));

ZipEntry ze;

while ((ze = zis.getNextEntry()) != null) {

//得到解压文件在当前存储的绝对路径

String filePath = destPath + File.separator + ze.getName();

if (ze.isDirectory()) {

new File(filePath).mkdirs();

} else {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int count;

while ((count = zis.read(buffer)) != -1) {

baos.write(buffer, 0, count);

}

byte[] bytes = baos.toByteArray();

File entryFile = new File(filePath);

//创建父目录

if (!entryFile.getParentFile().exists()) {

if (!entryFile.getParentFile().mkdirs()) {

throw new FileNotFoundException("zip entry mkdirs is failed");

}

}

//写文件

bos = new BufferedOutputStream(new FileOutputStream(entryFile));

bos.write(bytes);

bos.flush();

}

}

} finally {

closeQuietly(zis);

closeQuietly(bos);

}

}

/**

*@param srcPath 源文件的绝对路径,可以为文件或文件夹

*@param destPath 目标文件的绝对路径 /sdcard/.../file_name.zip

*@throws Exception 解压失败

*/

public static void compress(String srcPath, String destPath) throws Exception {

//参数检查

if (TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(destPath)) {

throw new IllegalArgumentException("srcPath or destPath is illegal");

}

File srcFile = new File(srcPath);

if (!srcFile.exists()) {

throw new FileNotFoundException("srcPath file is not exists");

}

File destFile = new File(destPath);

if (destFile.exists()) {

if (!destFile.delete()) {

throw new IllegalArgumentException("destFile is exist and do not delete.");

}

}

CheckedOutputStream cos = null;

ZipOutputStream zos = null;

try {

// 对目标文件做CRC32校验,确保压缩后的zip包含CRC32值

cos = new CheckedOutputStream(new FileOutputStream(destPath), new CRC32());

//装饰一层ZipOutputStream,使用zos写入的数据就会被压缩啦

zos = new ZipOutputStream(cos);

zos.setLevel(9);//设置压缩级别 0-9,0表示不压缩,1表示压缩速度最快,9表示压缩后文件最小;默认为6,速率和空间上得到平衡。

if (srcFile.isFile()) {

compressFile("", srcFile, zos);

} else if (srcFile.isDirectory()) {

compressFolder("", srcFile, zos);

}

} finally {

closeQuietly(zos);

}

}

private static void compressFolder(String prefix, File srcFolder, ZipOutputStream zos) throws IOException {

String new_prefix = prefix + srcFolder.getName() + "/";

File[] files = srcFolder.listFiles();

//支持空文件夹

if (files.length == 0) {

compressFile(prefix, srcFolder, zos);

} else {

for (File file : files) {

if (file.isFile()) {

compressFile(new_prefix, file, zos);

} else if (file.isDirectory()) {

compressFolder(new_prefix, file, zos);

}

}

}

}

/**

* 压缩文件和空目录

*

*@param prefix

*@param src

*@param zos

*@throws IOException

*/

private static void compressFile(String prefix, File src, ZipOutputStream zos) throws IOException {

//若是文件,那肯定是对单个文件压缩

//ZipOutputStream在写入流之前,需要设置一个zipEntry

//注意这里传入参数为文件在zip压缩包中的路径,所以只需要传入文件名即可

String relativePath = prefix + src.getName();

if (src.isDirectory()) relativePath += "/";//处理空文件夹

ZipEntry entry = new ZipEntry(relativePath);

//写到这个zipEntry中,可以理解为一个压缩文件

zos.putNextEntry(entry);

InputStream is = null;

try {

if (src.isFile()) {

is = new FileInputStream(src);

byte[] buffer = new byte[1024 << 3];

int len = 0;

while ((len = is.read(buffer)) != -1) {

zos.write(buffer, 0, len);

}

}

//该文件写入结束

zos.closeEntry();

} finally {

closeQuietly(is);

}

}

private static void closeQuietly(final Closeable closeable) {

try {

if (closeable != null) {

closeable.close();

}

} catch (final IOException ioe) {

// ignore

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值