JAVA中文件压缩、解压好方法分享

最近项目中有一个功能需要将文件压缩和解压,我这边最开始使用的是JDK中的类库,在网上找了一些样例,或多或少总是存在一些BUG,而且中文路径乱码的问题始终不能解决。没办法最终只有换方案,最后使用了apache-ant中的工具类来实现的,并且测试通过。源码也是从网上找到的,做了少量修改,这里给大家分享一下。

package com.aeai.zip;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.Enumeration;

import java.util.zip.CRC32;

import java.util.zip.CheckedOutputStream;

import java.util.zip.Deflater;

import java.util.zip.ZipException;

import org.apache.tools.zip.ZipEntry;

import org.apache.tools.zip.ZipFile;

import org.apache.tools.zip.ZipOutputStream;

/**

* 利用apache提供的ant.jar,提供对单个文件与目录的压缩,并支持是否需要创建压缩源目录、中文路径

*

* @Title

* @Description:ZipCompress

* @Version 1.2

*/

publicclass ZipCompress {

privatestaticbooleanisCreateSrcDir= true;// 是否创建源目录

/**

* 对文件夹或者文件进行压缩

*

* @Time 2012-3-9 上午09:32:35 create

* @param src

*      文件路径(全)

* @param archive

*      压缩路径(全)

* @param comment

*      压缩包注释

* @throws FileNotFoundException

* @throws IOException

*/

publicstaticvoid writeByApacheZipOutputStream(Stringsrc, String archive,

String comment) throws FileNotFoundException,IOException {

// ----压缩文件:

FileOutputStream f = newFileOutputStream(archive);

// 使用指定校验和创建输出流

CheckedOutputStream csum = new CheckedOutputStream(f, new CRC32());

ZipOutputStream zos = new ZipOutputStream(csum);

// 支持中文

zos.setEncoding("GBK");

BufferedOutputStream out = newBufferedOutputStream(zos);

// 设置压缩包注释

zos.setComment(comment);

// 启用压缩

zos.setMethod(ZipOutputStream.DEFLATED);

// 压缩级别为最强压缩,但时间要花得多一点

zos.setLevel(Deflater.BEST_COMPRESSION);

File srcFile = new File(src);

if (!srcFile.exists()

|| (srcFile.isDirectory()&& srcFile.list().length == 0)) {

thrownew FileNotFoundException(

"File must exist and  ZIP filemust have at least one entry.");

}

// 获取压缩源所在父目录

src = src.replaceAll("\\\\", "/");

String prefixDir = null;

if (srcFile.isFile()) {

prefixDir = src.substring(0,src.lastIndexOf("/") + 1);

} else {

prefixDir = (src.replaceAll("/$", "") + "/");

}

// 如果不是根目录

if (prefixDir.indexOf("/") != (prefixDir.length() - 1)

&& isCreateSrcDir){

prefixDir = prefixDir.replaceAll("[^/]+/$","");

}

// 开始压缩

writeRecursive(zos, out, srcFile,prefixDir);

out.close();

// 注:校验和要在流关闭后才准备,一定要放在流被关闭后使用

System.out.println("Checksum: " +csum.getChecksum().getValue());

}

/**

* 使用 org.apache.tools.zip.ZipFile 解压文件,它与 java 类库中的 java.util.zip.ZipFile

* 使用方式是一新的,只不过多了设置编码方式的接口。

*

* 注,apache没有提供 ZipInputStream类,所以只能使用它提供的ZipFile 来读取压缩

文件。

*

* @param archive

*           压缩包路径

* @param decompressDir

*           解压路径

* @throws IOException

* @throws FileNotFoundException

* @throws ZipException

*/

publicstaticvoid readByApacheZipFile(Stringarchive, String decompressDir)

throws IOException, FileNotFoundException,ZipException {

BufferedInputStream bi;

ZipFile zf = new ZipFile(archive, "GBK");// 支持中文

Enumeration<?> e =zf.getEntries();

while (e.hasMoreElements()) {

ZipEntry ze2 = (ZipEntry)e.nextElement();

String entryName = ze2.getName();

String path = decompressDir + "/" + entryName;

if (ze2.isDirectory()) {

System.out.println("正在创建解压目录 - " + entryName);

File decompressDirFile = new File(path);

if (!decompressDirFile.exists()) {

decompressDirFile.mkdirs();

}

} else {

System.out.println("正在创建解压文件 - " + entryName);

String fileDir =path.substring(0, path.lastIndexOf("/"));

File fileDirFile = new File(fileDir);

if (!fileDirFile.exists()) {

fileDirFile.mkdirs();

}

BufferedOutputStream bos = new BufferedOutputStream(

newFileOutputStream(decompressDir + "/" + entryName));

bi = new BufferedInputStream(zf.getInputStream(ze2));

byte[] readContent = newbyte[1024];

int readCount = bi.read(readContent);

while (readCount != -1) {

bos.write(readContent, 0,readCount);

readCount =bi.read(readContent);

}

bos.close();

}

}

zf.close();

}

/**

* 递归压缩

*

* 使用 org.apache.tools.zip.ZipOutputStream 类进行压缩,它的好处就是支持中文路径,而Java类库中的

* java.util.zip.ZipOutputStream 压缩中文文件名时压缩包会出现乱码。使用 apache中的这个类与 java

* 类库中的用法是一新的,只是能设置编码方式了。

*

* @param zos

* @param bo

* @param srcFile

* @param prefixDir

* @throws IOException

* @throws FileNotFoundException

*/

privatestaticvoidwriteRecursive(ZipOutputStream zos

,

BufferedOutputStream bo, FilesrcFile, String prefixDir)

throws IOException, FileNotFoundException {

ZipEntry zipEntry;

String filePath =srcFile.getAbsolutePath().replaceAll("\\\\", "/")

.replaceAll("//", "/");

if (srcFile.isDirectory()) {

filePath = filePath.replaceAll("/$", "") + "/";

}

String entryName =filePath.replace(prefixDir, "").replaceAll("/$", "");

if (srcFile.isDirectory()) {

if (!"".equals(entryName)) {

System.out.println("正在创建目录 - " + srcFile.getAbsolutePath()

+ " entryName=" + entryName);

// 如果是目录,则需要在写目录后面加上 /

zipEntry = new ZipEntry(entryName + "/");

zos.putNextEntry(zipEntry);

}

File srcFiles[] =srcFile.listFiles();

for (int i = 0; i < srcFiles.length; i++) {

writeRecursive(zos, bo,srcFiles[i], prefixDir);

}

} else {

System.out.println("正在写文件 - " + srcFile.getAbsolutePath()

+" entryName=" + entryName);

BufferedInputStream bi = new BufferedInputStream(

new FileInputStream(srcFile));

// 开始写入新的ZIP文件条目并将流定位到条目数据的开始处

zipEntry = new ZipEntry(entryName);

zos.putNextEntry(zipEntry);

byte[] buffer = newbyte[1024];

int readCount = bi.read(buffer);

while (readCount != -1) {

bo.write(buffer, 0, readCount);

readCount = bi.read(buffer);

}

// 注,在使用缓冲流写压缩文件时,一个条件完后一定要刷新一把,不

// 然可能有的内容就会存入到后面条目中去了

bo.flush();

// 文件读完后关闭

bi.close();

}

}

/**

* @param args

* @throws IOException

*/

publicstaticvoid main(String[] args) throws IOException {

//writeByApacheZipOutputStream("D:/data2", "D:/data2.zip","");

readByApacheZipFile("D:/data2.zip","D:/data3");

}

}

时间: 2024-12-12 06:54:34

JAVA中文件压缩、解压好方法分享的相关文章

linux下各种文件压缩解压(转载)

Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲tar命令的基本用法:  tar命令的选项有很多(用man tar可以查看到),但常用的就那么几个选项,下面 来举例说明一下:  # tar -cf all.tar *.jpg  这条命令是将所有.jpg的文件打成一个名为all.tar的包.-c是表示产生新的包 ,-f指定包的文件名.  # tar -

linux驱动系列之文件压缩解压小节(转)

转至网页:http://www.jb51.net/LINUXjishu/43356.html Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲tar命令的基本用法: tar命令的选项有很多(用man tar可以查看到),但常用的就那么几个选项,下面 来举例说明一下: # tar -cf all.tar *.jpg 这条命令是将所有.jpg的文件打成一

CompressUtils相关代码,java中文件压缩或解压已经文件的基本操作等方法

java中一些场合我们需要,对上传的压缩包中的内容进行处理,这个时候就用到了解压操作,还有压缩的操作等等,这里直接贴一下代码,以备今后自己可能会用到,还有共享给需要的小伙伴们. import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExceptio

tar.gz文件压缩解压方法

文件的压缩及解压命令老是记不住,所以简单做了一下整理. 1.tar.gz文件解压 # tar cvfz backup.tar.gz /xxx/ -c, --create create a new archive -v, --verbose verbosely list files processed -f, --file [HOSTNAME:]F use archive file or device F (default /dev/rmt0) -z, --gzip, --ungzip filte

Linux之文件压缩解压命令

gzip 命令名称:gzip 命令英文原意:GUN zip 命令所在路劲:bin/gzip 执行权限:所有用户 语法:gzip [文件] 功能描述:压缩文件 压缩后文件格式:.gz gunzip 命令名称:gunzip 命令英文原意:GUN unzip 命令所在路劲:bin/gunzip 执行权限:所有用户 语法:gunzip [压缩文件] 功能描述:解压缩 .gz的压缩文件 范例:gunzip djh.gz tar 命令名称:tar 命令所在路劲:bin/tar 执行权限:所有用户 语法:ta

Linux中的压缩解压命令小记

压缩:tar -cf new.tar data.txt 解压:tar -xf new.tar -C tmp/    ---->前提是tmp要先存在,这样才可以把解压后的文件放入这个tmp目录下面 压缩:gzip data.txt  (gzip只能压缩文件而不能压缩目录,压缩后以后缀名.gz存在,原先的文件将被覆盖) 解压:gzip -d data.txt.gz 压缩:bzip2 data.txt(也只能压缩文件,以.bz2存在) 解压:bzip2 -d data.txt.bz2 压缩:xz da

ST MCU生成PDF+文件压缩解压

之前碰到过,STM32F407上做文件压缩,无奈压缩文件时,哈夫曼编码需要耗费很大的RAM,导致失败.后来在论坛坛主的帮助下,了解了LZ77压缩. 今天看论坛的时候,了解到MCU上,用pdflib库,可以做PDF文件的生成.(https://github.com/AndreRenaud/PDFGen) 做下笔记,以备后面用到

基于哈夫曼编码的压缩解压程序

这个程序是研一上学期的课程大作业.当时,跨专业的我只有一点 C 语言和数据结构基础,为此,我查阅了不少资料,再加上自己的思考和分析,实现后不断调试.测试和完善,耗时一周左右,在 2012/11/19 完成.虽然这是一个很小的程序,但却是我完成的第一个程序. 源码托管在 Github:点此打开链接 一.问题描述: 名称:基于哈夫曼编码的文件压缩解压 目的:利用哈夫曼编码压缩存储文件,节省空间 输入:任何格式的文件(压缩)或压缩文件(解压) 输出:压缩文件或解压后的原文件 功能:利用哈夫曼编码压缩解

c#自带类实现的多文件压缩和解压

c#自带的System.IO.Compression命名空间下的压缩类实现的多文件压缩和解压功能,缺点是多文件压缩包的解压只能调用自身的解压方法,和现有的压缩软件不兼容.下面的代码没有把多文件的目录结构加进去 using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; namespace Test.Zip { class CompressHelper { /// <su