Java解压缩技术(一)ZIP压缩-解压缩

Java解压缩技术的实现 GZIP ZIP BZIP2系列实现

没啥好说的,都是些文件操作,直接贴代码

package com.ljh.zip;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @Desc: ZIP 压缩工具(文件压缩建议使用,支持文件夹解压缩)
 * ZIP可用于socket套接字流数据压缩(实现方式类似)
 * @author ljh
 * @date 2015-4-14 上午9:39:14
 */
public class ZipUtils {
	private static final int BUFFER = 1024;
	private static final String EXT = ".zip";
	private static final String BASE_DIR = "";
	private static final String PATH = "/"; // 符号"/"用来作为ZIP压缩文件内部的目录标识判断符[因为ZipEntry.isDirectory()方法内部是以'/'来作为目录标识符的]

	/**
	 * @Description: ZIP 数据压缩
	 * @author (ljh) @date 2015-4-13 下午6:00:52
	 * @param data
	 * @return
	 * @throws IOException
	 * @return byte[]
	 */
	public static byte[] compressData(byte[] data) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ZipOutputStream zipOS = new ZipOutputStream(baos);
		ZipEntry entry = new ZipEntry("zip");
		entry.setSize(data.length);
		zipOS.putNextEntry(entry);
		zipOS.write(data);
		zipOS.closeEntry();
		zipOS.close();
		baos.close();
		return baos.toByteArray();
	}

	/**
	 * @Description: ZIP 数据解压缩
	 * @author (ljh) @date 2015-4-13 下午6:00:42
	 * @param bytes
	 * @return
	 * @throws IOException
	 * @return byte[]
	 */
	public static byte[] uncompressData(byte[] data) throws IOException {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ZipInputStream zipIS = new ZipInputStream(bais);
		byte[] bytes = null;
		while (zipIS.getNextEntry() != null) {
			byte[] buf = new byte[BUFFER];
			int count;
			ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFFER);
			while ((count = zipIS.read(buf, 0, buf.length)) != -1) {
				baos.write(buf, 0, count);
			}
			bytes = baos.toByteArray();
			baos.flush();
			baos.close();
		}
		zipIS.close();
		bais.close();
		return bytes;
	}

	/**
	 * @Description: 文件压缩
	 * @author (ljh) @date 2015-4-14 上午9:32:52
	 * @param path
	 *            源文件路径
	 * @throws IOException
	 * @return void
	 */
	public static void compress(String srcPath) throws IOException {
		compress(new File(srcPath));
	}
	public static void compress(File srcFile) throws IOException {
		compress(srcFile, srcFile.getPath() + EXT);
	}
	public static void compress(String srcPath, String destPath) throws IOException {
		compress(new File(srcPath), new File(destPath));
	}
	public static void compress(File srcFile, String destPath) throws IOException{
		compress(srcFile, new File(destPath));
	}

	/**
	 * @Description: 开始文件压缩
	 * @author (ljh) @date 2015-4-14 上午10:54:06
	 * @param srcFile
	 * @param destFile
	 * @throws IOException
	 * @return void
	 */
	public static void compress(File srcFile, File destFile) throws IOException {
		CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());// 对输出文件做CRC32校验
		ZipOutputStream zipOS = new ZipOutputStream(cos);
		compress(srcFile, zipOS, BASE_DIR);
		zipOS.flush();
		zipOS.close();
		cos.close();
	}

	/**
	 * @Description: ZIP 文件/目录
	 * @author (ljh) @date 2015-4-14 下午12:41:33
	 * @param srcFile 源文件/目录
	 * @param zipOS 输出流
	 * @param basePath
	 * @throws IOException
	 * @return void
	 */
	public static void compress(File srcFile, ZipOutputStream zipOS, String basePath) throws IOException {
		if (srcFile.isDirectory()) {
			compressDir(srcFile, zipOS, basePath);
		} else {
			compressFile(srcFile, zipOS, basePath);
		}
	}

	/**
	 * @Description: ZIP 文件压缩
	 * @author (ljh) @date 2015-4-14 上午10:36:56
	 * @param file
	 * @param zipOS
	 * @throws IOException
	 * @return void
	 */
	private static void compressFile(File file, ZipOutputStream zipOS, String basePath) throws IOException {
		/**
		 * 压缩包内文件名定义 ,如果有多级目录,那么这里就需要给出包含目录的文件名 ,如果用WinRAR打开压缩包,中文名将显示为乱码
		 */
		ZipEntry entry = new ZipEntry(basePath + file.getName());
		zipOS.putNextEntry(entry);
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
		int count;
		byte[] buf = new byte[BUFFER];
		while ((count = bis.read(buf, 0, buf.length)) != -1) {
			zipOS.write(buf, 0, count);
		}
		bis.close();
		zipOS.closeEntry();
	}

	/**
	 * @Description: 目录压缩
	 * @author (ljh) @date 2015-4-14 下午12:40:49
	 * @param dirFile
	 * @param zipOS
	 * @param basePath
	 * @throws IOException
	 * @return void
	 */
	private static void compressDir(File dirFile, ZipOutputStream zipOS, String basePath) throws IOException {
		File[] files = dirFile.listFiles();
		// 构建空目录
		if (files.length < 1) {// 空目录
			ZipEntry entry = new ZipEntry(basePath + dirFile.getName() + PATH);
			zipOS.putNextEntry(entry);
			zipOS.closeEntry();
		}
		for (File file : files) {
			compress(file, zipOS, basePath + dirFile.getName() + PATH); // 递归压缩
		}
	}

	//---------------------------------------------------------------
	/**
	 * @Description: ZIP文件解压缩
	 * @author (ljh) @date 2015-4-14 下午12:46:25
	 * @param srcPath
	 * @throws IOException
	 * @return void
	 */
	public static void uncompress(String srcPath) throws IOException {
		uncompress(new File(srcPath));
	}
	public static void uncompress(File srcFile) throws IOException {
		uncompress(srcFile, srcFile.getParent());
	}
	public static void uncompress(String srcPath, String destPath) throws IOException {
		uncompress(new File(srcPath), destPath);
	}
	public static void uncompress(File srcFile, String destPath) throws IOException {
		uncompress(srcFile, new File(destPath));
	}

	/**
	 * @Description: 开始ZIP文件解压缩
	 * @author (ljh) @date 2015-4-14 下午12:47:00
	 * @param srcFile
	 * @param destFile
	 * @throws IOException
	 * @return void
	 */
	public static void uncompress(File srcFile, File destFile) throws IOException {
		CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32());
		ZipInputStream zipIS = new ZipInputStream(cis);
		uncompress(zipIS, destFile);
		zipIS.close();
		cis.close();
	}

	private static void uncompress(ZipInputStream zipIS, File destFile) throws IOException {
		ZipEntry entry = null;
		while ((entry = zipIS.getNextEntry()) != null) {
			String dir = destFile.getPath() + File.separator + entry.getName();
			File dirFile = new File(dir);
			fileProber(dirFile);//递归创建dirFile父目录
			if (entry.isDirectory()) {
				dirFile.mkdirs();
			} else {
				uncompressFile(zipIS, dirFile);
			}
			zipIS.closeEntry();
		}
	}

	/**
	 * @Description: 当父目录不存在时,创建目录
	 * @author (ljh) @date 2015-4-14 下午12:54:25
	 * @param dirFile
	 * @return void
	 */
	private static void fileProber(File dirFile) {
		File parentFile = dirFile.getParentFile();
		if (!parentFile.exists()) {
			fileProber(parentFile);	//递归寻找上级目录并递归创建
			parentFile.mkdir();
		}
	}

	/**
	 * 文件解压缩
	 * @throws IOException
	 */
	private static void uncompressFile(ZipInputStream zipIS, File destFile) throws IOException {
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
		int count;
		byte buf[] = new byte[BUFFER];
		while ((count = zipIS.read(buf, 0, buf.length)) != -1) {
			bos.write(buf, 0, count);
		}
		bos.close();
	}

	// --------------------------------------------
}

测试方法:

	/**
	 * @Description: 被压缩数据较大才比较明显[测试发现中文byte字节大于200的时候才有明显的压缩,英文150才明显]
	 * @author (ljh) @date 2015-4-14 上午11:33:13
	 * @throws IOException
	 * @return void
	 */
//	@org.junit.Test
	private static void testZIP() throws IOException {
		byte[] bytes = "啊了简单概括啦啦as了的价格了看洒落的空间关了撒娇g9w9eijgslkj是肯德基了感觉是肯德基斤斤计较斤斤计较斤斤计较斤斤计较斤斤计较斤斤计较死死死死死死死死死死死死啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦".getBytes();
		// 对bytes压缩
		// 验证一下压缩后的效果对比
		System.out.println("压缩前:");
		System.out.println(bytes.length);
		for (byte b : bytes) {
			System.out.print(b + " ");
		}
		System.out.println();
		System.out.println("压缩后:");
		byte[] bytes2 = ZipUtils.compressData(bytes);
		System.out.println(bytes2.length);
		for (byte b : bytes2) {
			System.out.print(b + " ");
		}
		System.out.println();
		System.out.println("解压缩后:");
		byte[] byte22 = ZipUtils.uncompressData(bytes2);
		System.out.println(byte22.length);
		for (byte b : byte22) {
			System.out.print(b+" ");
		}
		System.out.println();

//        ZipUtils.compress("F:\\test\\test1");
//		ZipUtils.uncompress("F:\\test\\test1.zip");
		//要压缩文件夹请参考ZIPUtils自行实现
	}

点我下载相关源码

时间: 2024-11-05 02:33:16

Java解压缩技术(一)ZIP压缩-解压缩的相关文章

Qt之zip压缩/解压缩(QuaZIP)

摘要: 简述 QuaZIP是使用Qt/C++对ZLIB进行简单封装的用于压缩及解压缩ZIP的开源库.适用于多种平台,利用它可以很方便的将单个或多个文件打包为zip文件,且打包后的zip文件可以通过其它工具打开. 简述 QuaZIP是使用Qt/C++对ZLIB进行简单封装的用于压缩及解压缩ZIP的开源库.适用于多种平台,利用它可以很方便的将单个或多个文件打包为zip文件,且打包后的zip文件可以通过其它工具打开. Qt中提供了qCompress/qUncompress来进行文件的压缩与解压,但存在

java工具类 文件zip压缩 base64 加密,base64解密 zip解压

package com.cfam.utils; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;

AntZipUtils【基于Ant的Zip压缩解压缩工具类】

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 Android 压缩解压zip文件一般分为两种方式: 基于JDK的Zip压缩工具类 该版本存在问题:压缩时如果目录或文件名含有中文,压缩后会变成乱码: 使用Java的zip包可以进行简单的文件压缩和解压缩处理时,但是遇到包含中文汉字目录或者包含多层子目录的复杂目录结构时,容易出现各种各样的问题. 基于Ant的Zip压缩工具类 需要第三方JAR包:Apache的ant.jar: 解决了上面存在的问题. 效果图 代码分析 常用的方法: 压缩

zip压缩解压缩 项目icsharpcode-SharpZipLib-e012155

大家可以到http://www.icsharpcode.net/opensource/sharpziplib/ 下载SharpZiplib的最新版本,支持Zip, GZip, BZip2 和Tar格式,本作者的项目代码如下 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using S

nodejs压缩解压缩(加密)

1.shell/cmd命令行压缩解压缩 (1)zip压缩解压缩 zip压缩:zip -rP{密码} <目标文件.zip> <源文件> //默认覆盖现有文件 zip解压缩:zip -oP{密码} <源文件.zip> //默认覆盖现有文件 (2)rar压缩解压缩 说明: linux需要下载rarlinux,然后压缩,make编译后,即可使用. rar压缩:rar a -p{密码} <目标文件.rar> <源文件> -y //默认覆盖现有文件 例如:r

Java解压缩技术(二)GZIP压缩-解压缩(

Java解压缩技术的实现 GZIP ZIP BZIP2 没啥好说的,都是些文件IO操作 package com.ljh.gzip; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOExcept

Java解压缩技术(三)BZIP2压缩-解压缩

Java解压缩技术的实现 GZIP ZIP BZIP2 与GZIP  ZIP 不同的是BZIP2在Java中没有实现,BZIP2的实现是Apache提供的Commons-Compress.jar来实现的 关于 Commons Compress请移步:http://commons.apache.org/proper/commons-compress/ 还是直接上代码 package com.ljh.bzip2; import java.io.ByteArrayInputStream; import

JAVA压缩 解压缩zip 并解决linux下中文乱码

1. [代码][Java]代码   1:再压缩前,要设置linux模式, 需要使用第三方ant-1.6.5.jar  如果是文件目录,则ZipEntry zipEntry=new ZipEntry(basePath + System.getProperties().getProperty("file.separator"));zipEntry.setUnixMode(755);//解决linux乱码 如果是文件,则 ZipEntry zipEntry=new ZipEntry(base

java.util.zip压缩打包文件总结二: ZIP解压技术

一.简述 解压技术和压缩技术正好相反,解压技术要用到的类:由ZipInputStream通过read方法对数据解压,同时需要通过CheckedInputStream设置冗余校验码,如: CheckedInputStream cis = new CheckedInputStream(new FileInputStream( srcFile), new CRC32()); ZipInputStream zis = new ZipInputStream(cis); 需要注意的是,在构建解压文件时,需要