`

org.apache.tools.zip实现文件的压缩和解压,支持中文

    博客分类:
  • J2EE
 
阅读更多
刚开始用java.util.Zip,发现不支持中文(网上有修改的方法,但比较麻烦)
后改用org.apache.tools.zip
org.apache.tools.zip的使用网上有更简单的例子
下面的程序根据实际需求,实现了压缩指定目录下指定文件的方法


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

import common.Logger;//in jxl.jar (excel)

public class ZipUtil {

	/**
	 * zip操作帮助类
	 * bylijinnan
	 */
	final static Logger logger = Logger.getLogger(ZipUtil.class);

	/**
	 * 打包指定目录下所有文件,包括子文件夹
	 * @param sourceFolder	要打包的文件目录
	 * @param outputFolder	生成的压缩文件存放的目录
	 * @param zipFileName	生成的压缩文件名
	 * @throws IOException
	 */
	public static void zipFolder(String sourceFolder, String outputFolder,String zipFileName, String encoding) throws IOException {
		if (isEmptyStr(sourceFolder) || isEmptyStr(outputFolder) || isEmptyStr(zipFileName)) {
			logger.error("invalid parameters.");
			return;
		}
		sourceFolder = formatFilePath(sourceFolder);
		outputFolder = formatFilePath(outputFolder);
		List<String> filelist = generateFileList(sourceFolder);
		zipFileList(filelist, sourceFolder, outputFolder, zipFileName, encoding);
	}
	
	
	/**
	 * 打包指定的文件。要打包的文件在文件列表中指定
	 * @param filelist	要打包的文件列表,这些文件是绝对路径
	 * @param outputFullFileName	生成的压缩文件全名,目录+文件名
	 * @throws IOException
	 */
	public static void zipFileList(List<String> filelist, String sourceFolder, String outputFolder, String zipFileName, String encoding) throws IOException {
		if (filelist == null || filelist.isEmpty()) {
			logger.error("no files to be zip. filelist is null or empty.");
			return;
		}
		if (isEmptyStr(outputFolder) || isEmptyStr(zipFileName)) {
			logger.error("outputFolder and zipFileName are unspecified.");
			return;
		}
		
		sourceFolder = formatFilePath(sourceFolder);
		outputFolder = formatFilePath(outputFolder);
		if (isEmptyStr(encoding)) {
			encoding = "UTF-8";
		}
		
		File outputDir = new File(outputFolder);
		if (!outputDir.exists()) {
			outputDir.mkdirs();
		}
		
		byte[] buffer = new byte[1024];

		String outputFullFileName = (outputFolder + "/" + zipFileName);
		FileOutputStream fos = new FileOutputStream(outputFullFileName);
		ZipOutputStream zos = new ZipOutputStream(fos);
		zos.setEncoding(encoding);
		logger.info("Output to Zip : " + outputFullFileName);

		for (String file : filelist) {
			if (isEmptyStr(file)) {
				continue;
			}
			logger.info("File Added : " + file);
			ZipEntry ze = new ZipEntry(file);	//这里用的是相对路径
			zos.putNextEntry(ze);

			FileInputStream in = new FileInputStream(sourceFolder + "/" + file);		//这里是绝对路径

			int len;
			while ((len = in.read(buffer)) > 0) {
				zos.write(buffer, 0, len);
			}

			in.close();
		}

		zos.closeEntry();
		// remember close it
		zos.close();

		logger.info("Compress Done");

	}

	/**
	 * Traverse a directory and get all files(include the files in sub directory), add the file into fileList and return it.
	 * 
	 * @param sourceFolder
	 *            file or directory
	 * @return filelist
	 */
	public static List<String> generateFileList(String sourceFolder) {
		List<String> filelist = null;
		if (!isEmptyStr(sourceFolder)) {
			sourceFolder = formatFilePath(sourceFolder);
			filelist = new ArrayList<String>();
			File node = new File(sourceFolder);
			generateFileListHelper(sourceFolder, node, filelist);
		}
		return filelist;
	}
	
	private static void generateFileListHelper(String sourceFolder, File node, List<String> filelist) {

		// add file only
		if (node.isFile()) {
			String absoluteFile = node.getAbsoluteFile().toString();
			String filepath = generateZipEntry(sourceFolder, absoluteFile);
			filelist.add(filepath);
		}

		if (node.isDirectory()) {
			String[] subNote = node.list();
			for (String filename : subNote) {
				File subFile = new File(node, filename);
				generateFileListHelper(sourceFolder, subFile, filelist);
			}
		}

	}

	/**
	 * Format the file path for zip.
	 * Delete the "SOURCE_FOLDER" directory info,e.g.
	 * d:\ziptest\tmpty.txt 		--> tmpty.txt 
	 * d:\ziptest\sub\t.xls 	-->	sub\t.xls
	 * 
	 * @param file
	 *            file path
	 * @return Formatted file path.
	 */
	private static String generateZipEntry(String sourceFolder, String file) {
		logger.debug("sourceFolder=" + sourceFolder);
		logger.debug("file=" + file);
		String formattedPath = file.substring(sourceFolder.length() + 1);
		formattedPath = formatFilePath(formattedPath);
		logger.debug("formattedPath=" + formattedPath);
		return formattedPath;
	}
	
	/**
	 * 将文件路径中的分隔符转换成"/",并去掉最后的分隔符(如果有)
	 * @param str	文件路径 
	 * @return 格式化后的文件路径
	 */
	public static String formatFilePath(String str) {
		if (str != null && str.length() !=0) {
			 str = str .replaceAll("\\\\", "/");
		}
		if (str.endsWith("/")) {
			str = str.substring(0, str.length()-1);
		}
		return str;
	}
	
	private static boolean isEmptyStr(String str) {
		return str == null || str.length() == 0;
	}
	
	/**
	 * 解压zip文件,支持子文件夹和中文
	 * @param zipFileFullName .zip文件的完整名字,包括文件夹路径
	 * @param outputFolder	解压到指定的文件夹。完整路径,如果不指定或者为null,则默认解压到压缩文件所在的当前文件夹
	 * @param encoding 编码格式
	 */
	@SuppressWarnings("rawtypes")
	public static void unzip(String zipFileFullName, String outputFolder, String encoding) {
		if (zipFileFullName == null || zipFileFullName.length() == 0) {
			return;
		}
		if (!zipFileFullName.endsWith(".zip")) {
			logger.error(zipFileFullName + " is not a zip file.");
			return;
		}
		//change file separator to "/"
		zipFileFullName = zipFileFullName.replaceAll("\\\\", "/");
		//find outputFolder
		String inputFolder = zipFileFullName.replaceAll("/[^/]+\\.zip", "");
		if (outputFolder == null || outputFolder.length() == 0) {
			outputFolder = inputFolder;
		}
		outputFolder = outputFolder.replaceAll("\\\\", "/");
		
		File outputFolderFile = new File(outputFolder);
		if (!outputFolderFile.exists()) {
			outputFolderFile.mkdirs();
		}
		try {
			ZipFile zip = new ZipFile(zipFileFullName, encoding);
			Enumeration zipFileEntries = zip.getEntries();

			while (zipFileEntries.hasMoreElements()) {
				ZipEntry entry =  (ZipEntry) zipFileEntries.nextElement();
				String entryName = entry.getName();
				logger.debug("Extracting,entryName=" + entryName);
				
				/*用本程序中ZipUtil.zipFolder或者ZipUtil.zipFileList生成的zip文件,如果有子文件夹,entry.getName()会直接得到文件而略过了子文件夹:
				 * 程序生成,解压时输出:
				 * Extracting,entryName=sub/subsub/test.txt
				 * 压缩软件7-Zip生成,解压时输出:
				 * Extracting,entryName=sub/subsub/ 
				 * Extracting,entryName=sub/subsub/test.txt
				 * 因此要区别对待
				 */
				
				int lastSlashPos = entryName.lastIndexOf("/");
				if (lastSlashPos != -1 ){
					String folderStr = outputFolder + "/" + entryName.substring(0, lastSlashPos);
					File folder = new File(folderStr);
					if (!folder.exists()) {
						folder.mkdirs();
					}
				}
				if (!entryName.endsWith("/")) {		//this entry is not a directory.
					File outFile = new File(outputFolder + "/" + entryName);
					FileOutputStream fos = new FileOutputStream(outFile);
					Writer bw = new BufferedWriter(new OutputStreamWriter(fos, encoding));
					
					InputStream in = zip.getInputStream(entry);
					Reader reader = new InputStreamReader(in, encoding); 
					BufferedReader br =  new BufferedReader(reader);
					
					String line;
					while ((line = br.readLine()) != null) {
						bw.write(line);
					}
					bw.close();
				}
			}

		} catch (Exception e) {
			logger.error("errors occur when decompressing.");
			e.printStackTrace();
		}
	}
	
	public static void main(String[] argv) {
		
		String sourceFolder = "d:/ziptest";
		String outputFolder = "d:/ziptest";
		String outputFileName = "ziptest.zip";
		try {
			zipFolder(sourceFolder, outputFolder, outputFileName, "GB2312");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		String zipFileFullName = "d:\\ziptest\\ziptest.zip";
		unzip(zipFileFullName, "d:\\ziptest\\unzip", "GB2312");
		
	}

	
}



0
0
分享到:
评论

相关推荐

    org.apache.tools.zip.*文件打包需要的jar包

    import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream;...需要的jar包,压缩zip包和解压zip包,远程打包,文件批量下载、文件批量上传

    org.apache.tools.zip解决解压乱码问题

    import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream; /** * * 类名: ZipUtil.java * 描述:压缩/解压缩zip包处理类 * 创建...

    java压缩中文处理使用org.apache.tools.zip已经打包成jar

    java压缩中文处理使用org.apache.tools.zip已经打包成jar 只要放在LIB文件夹下,然后在JSP 或 JAVA 里引用即可。 &lt;%@ page language="java" import="java.sql.*,java.io.*,org.apache.tools.zip.Zip" pageEncoding=...

    java压缩使用org.apache.tools.zip包解决中文文件名

    http://mirror.bjtu.edu.cn/apache//ant/source/apache-ant-1.8.2-src.zip 使用我自己包,直接放到WEB-INF\classes下解压即可, 在程序中加上 outf.setEncoding("gbk");即可 下面是我的多个文件压缩成一个的压缩...

    java 操作Zip文件(压缩、解压、加密).zip

    Java操作Zip文件主要涉及到对文件和目录的压缩与解压缩,以及在必要时对压缩文件进行加密处理。这里我们重点讨论使用两个库:`zip4j`和`Apache Ant`来实现这些功能。 1. **zip4j库**:`zip4j-1.3.2.jar`是一个用...

    apache依赖包.zip

    首先,需要解压所有文件,然后按照特定顺序编译和安装:先安装zlib,再是OpenSSL,接着是APR和APR-Util,之后是PCRE,最后是Apache本身以及其他依赖于这些库的模块(如mod_wsgi)。在编译和安装过程中,确保遵循每个...

    apache-ant-zip-2.3.jar.zip

    Apache Ant Zip 2.3.jar 特别关注的是处理ZIP文件格式的操作,包括创建、解压和操作ZIP档案中的文件。这个特定的版本2.3可能包含了一些特定的修复或功能改进相对于之前的版本。由于在Maven仓库中找不到这个特定的...

    JAVA解压ZIP多层目录文件(需ant.jar

    这种方法利用了Apache Ant库中的`org.apache.tools.zip.ZipFile`类来实现解压功能。在实际应用中,这种方法非常实用,尤其是在需要处理复杂ZIP文件结构的情况下。 #### 方法参数 该方法接受三个参数: 1. **old...

    解压zip压缩文件,支持多文件目录解压,中文乱码问题

    在使用Java对ZIP压缩文件进行解压的方式中有两种,一种是使用apache提供的ant.jar工具包,但是如果ZIP文件中含有中文名称的文件,在解压后,文件名将出现乱码,另一种是使用Java自身JDK中java.util.zip包下工具类,...

    利用ant.jar解压缩zip包

    总的来说,利用Apache Ant的ant.jar库,无论是通过Java代码还是Ant构建文件,都能方便、高效地解压缩ZIP文件,而且对于包含中文文件名的情况,它提供了良好的支持。在实际开发中,理解并熟练运用这类工具可以极大地...

    java文件压缩源码

    在本例中,我们提到的实现方式是通过使用Apache Ant库中的`org.apache.tools.ant.taskdefs.Zip`类。Apache Ant是一个基于Java的任务驱动构建系统,它的任务库包含了丰富的功能,其中之一就是文件压缩。 `Zip`类提供...

    java操作压缩文件和解压文件实例代码(经测试)

    如果`ZipFileList.java`使用了Ant的功能,那么可能通过`org.apache.tools.ant.types.FileSet`选择要压缩的文件。 6. **注释和修改**:源代码中的注释是理解代码的关键。`ZipFileList.java`中的注释可能指导开发者...

    java解压ZIP文件

    - **org.apache.tools.zip**: Apache Commons Compress库中的`org.apache.tools.zip`包提供了一系列工具类,用于处理ZIP文件格式。这些工具比标准Java API更加强大且易于使用。 - **BufferedInputStream** 和 **...

    解压zip及rar文件依赖的jar包

    Zip和RAR是两种广泛使用的文件压缩格式,它们允许我们将多个文件和目录打包成一个单一的可传输文件,以节省存储空间和提高传输效率。本话题主要关注如何在Java环境中利用特定的库来处理这些压缩格式,特别是依赖于`...

    利用ant api做的遍历并解压各种压缩文件格式的源代码

    利用ant api做的遍历并解压各种压缩文件格式的源代码 支持 zip, (当然) gzip tar gz bz2 bz 文件包括ant.jar, 源代码 有问题可以留言,我会及时回复 ziptest下面是用来做测试的目录。 请解压到 C:\temp\ziptest ...

    java文件压缩与解压.doc

    通过上述分析,我们可以看出在Java中使用Apache Tools Zip库进行文件压缩与解压是非常便捷的。开发者只需要关注业务逻辑的编写,而具体的文件操作则由库内部实现。这种方式不仅简化了代码量,也提高了程序的可维护性...

    Java ZIP压缩一个或多个文件(解决中文名称乱码).rar

    用java.util.zipoutputstream压缩会出现中文的文件名乱码的情况,且无法设置字符集,这个版本用org.apache.tools.zip.ZipOutputStream压缩,可以自定义字符集,解决中文的文件名乱码问题。

    Java压缩文件目录成ZIP包最新技巧

    本文选择第二种方案进行介绍,即使用Apache Ant工具库中的Zip组件来实现对包含中文名的文件或目录的压缩。 #### 三、引入Apache Ant Zip组件 为了使用Apache Ant工具库中的Zip组件,首先需要将Ant的jar包添加到...

    java对zip、rar文件的压缩和解压缩

    - `Project` 和 `Expand` 类来自`org.apache.tools.ant`包,这是一个基于Apache Ant的工具集合。 - `setEncoding` 方法用于指定解压缩时的字符编码,以解决不同压缩软件使用的编码不一致问题。 #### RAR文件的...

Global site tag (gtag.js) - Google Analytics