在JAVA中解决Zip压缩乱码问题

简介: Java自带的zip压缩工具,可以让我们方便的压缩与解压缩,但是就是默认编码UTF-8没法改(至少我没找到,如果谁找到了,别忘记告诉我,我也不想用第三方的Jar包),虽然使用Java写打压缩与解压缩没问题,但是中文字符在WinRAR里面全是乱码。 所以我采用了Ant包中的压缩功能。 多余的话不多说了,代码才是硬道理,直接上代码吧。顺便说一下,该程序依赖于ant包,但是如果你只用到压缩,

Java自带的zip压缩工具,可以让我们方便的压缩与解压缩,但是就是默认编码UTF-8没法改(至少我没找到,如果谁找到了,别忘记告诉我,我也不想用第三方的Jar包),虽然使用Java写打压缩与解压缩没问题,但是中文字符在WinRAR里面全是乱码。

所以我采用了Ant包中的压缩功能。

多余的话不多说了,代码才是硬道理,直接上代码吧。顺便说一下,该程序依赖于ant包,但是如果你只用到压缩,你可以用WinRAR打开这个Ant.jar文件,删除org.apache.tools.zip包以外的所有class,就可以极度瘦身了。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

/**
 * 压缩解压缩<br>
 * 该程序依赖于Ant包 Ant 下载地址:http://ant.apache.org/
 * 
 * @author <a href="mailto:xzknet@gmail.com">Ken_xu</a>
 * @version 1.0 Copyright 2011年7月8日11:33:39
 */
public class KenZip {
	private Log log = LogFactory.getLog(this.getClass().getName());
	private static int BUF_SIZE = 1024;
	private static String ZIP_ENCODEING = "GBK";

	public KenZip() {
		this(1024 * 10);
	}

	public KenZip(int bufSize) {
		BUF_SIZE = bufSize;
	}

	/**
	 * 压缩文件或文件夹
	 * 
	 * @param zipFileName
	 * @param inputFile
	 * @throws Exception
	 */
	public void zip(String zipFileName, String inputFile) throws Exception {
		zip(zipFileName, new File(inputFile));
	}

	/**
	 * 压缩文件或文件夹
	 * 
	 * @param zipFileName
	 * @param inputFile
	 * @throws Exception
	 */
	public void zip(String zipFileName, File inputFile) throws Exception {
		// 未指定压缩文件名,默认为"ZipFile"
		if (zipFileName == null || zipFileName.equals(""))
			zipFileName = "ZipFile";

		// 添加".zip"后缀
		if (!zipFileName.endsWith(".zip"))
			zipFileName += ".zip";

		// 创建文件夹
		String path = Pattern.compile("[\\/]").matcher(zipFileName).replaceAll(File.separator);
		int endIndex = path.lastIndexOf(File.separator);
		path = path.substring(0, endIndex);
		File f = new File(path);
		f.mkdirs();
		// 开始压缩
		{
			ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName)));
			zos.setEncoding(ZIP_ENCODEING);
			compress(zos, inputFile, "");
			log.debug("zip done");
			zos.close();
		}
	}

	/**
	 * 解压缩zip压缩文件到指定目录
	 * 
	 * @param unZipFileName
	 * @param outputDirectory
	 * @throws Exception
	 */
	public void unZip(String unZipFileName, String outputDirectory) throws Exception {
		// 创建输出文件夹对象
		File outDirFile = new File(outputDirectory);
		outDirFile.mkdirs();
		// 打开压缩文件文件夹
		ZipFile zipFile = new ZipFile(unZipFileName, ZIP_ENCODEING);
		for (Enumeration entries = zipFile.getEntries(); entries.hasMoreElements();) {
			ZipEntry ze = (ZipEntry) entries.nextElement();
			File file = new File(outDirFile, ze.getName());
			if (ze.isDirectory()) {// 是目录,则创建之
				file.mkdirs();
				log.debug("mkdir " + file.getAbsolutePath());
			} else {
				File parent = file.getParentFile();
				if (parent != null && !parent.exists()) {
					parent.mkdirs();
				}
				log.debug("unziping " + ze.getName());
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				InputStream is = zipFile.getInputStream(ze);
				this.inStream2outStream(is, fos);
				fos.close();
				is.close();
			}
		}
		zipFile.close();
	}

	/**
	 * 压缩一个文件夹或文件对象到已经打开的zip输出流 <b>不建议直接调用该方法</b>
	 * 
	 * @param zos
	 * @param f
	 * @param fileName
	 * @throws Exception
	 */
	public void compress(ZipOutputStream zos, File f, String fileName) throws Exception {
		log.debug("Zipping " + f.getName());
		if (f.isDirectory()) {
			// 压缩文件夹
			File[] fl = f.listFiles();
			zos.putNextEntry(new ZipEntry(fileName + "/"));
			fileName = fileName.length() == 0 ? "" : fileName + "/";
			for (int i = 0; i < fl.length; i++) {
				compress(zos, fl[i], fileName + fl[i].getName());
			}
		} else {
			// 压缩文件
			zos.putNextEntry(new ZipEntry(fileName));
			FileInputStream fis = new FileInputStream(f);
			this.inStream2outStream(fis, zos);
			fis.close();
			zos.closeEntry();
		}
	}

	private void inStream2outStream(InputStream is, OutputStream os) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(is);
		BufferedOutputStream bos = new BufferedOutputStream(os);
		int bytesRead = 0;
		for (byte[] buffer = new byte[BUF_SIZE]; ((bytesRead = bis.read(buffer, 0, BUF_SIZE)) != -1);) {
			bos.write(buffer, 0, bytesRead); // 将流写入
		}
	}

	public static void main(String[] args) {
		try {
			KenZip t = new KenZip();
			t.zip("d:\\temp\\xzk2.zip", "E:\\驾校模拟考试");
			t.unZip("d:\\temp\\xzk2.zip", "E:\\驾校模拟考试2");
		} catch (Exception e) {
			e.printStackTrace(System.out);
		}
	}
}



相关文章
|
2月前
|
存储 Java 文件存储
如何用 Java 压缩 ZIP 文件?
【2月更文挑战第21天】
37 1
|
4月前
|
存储 Java Android开发
IO流:java中解码和编码出现乱码说明及代码实现
IO流:java中解码和编码出现乱码说明及代码实现
|
1月前
|
JSON Java 应用服务中间件
JavaWeb项目之乱码问题及如何解决
JavaWeb项目之乱码问题及如何解决
|
4月前
|
存储 算法 Java
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
|
6月前
|
Java
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
51 0
|
5月前
|
Java 容器
idea中关于java的图形化界面编程awt_container容器中Button(按钮)上汉字是乱码或者小方框的解决方法
idea中关于java的图形化界面编程awt_container容器中Button(按钮)上汉字是乱码或者小方框的解决方法
49 0
|
25天前
|
Java 大数据 测试技术
Java对象头压缩---- 永久为Java应用“降本增效”
本文介绍了一下OpenJDK的最新技术,对象头压缩,来大幅优化Java对象的内存占用。
|
6月前
|
存储 算法 NoSQL
Zstandard (zstd)压缩算法在JAVA上的使用
Zstandard (zstd)压缩算法在JAVA上的使用
289 0
|
2月前
|
Java API 数据库
解决Java中文显示乱码问题的原因与方案
解决Java中文显示乱码问题的原因与方案
222 0
|
5月前
|
Java API Apache
Java之打印流,压缩流,工具包的详细解析
4. 打印流 4.1 概述 平时我们在控制台打印输出,是调用print方法和println方法完成的,这两个方法都来自于java.io.PrintStream类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。 4.2 PrintStream类
32 0