您的位置:首页 > 编程语言 > Java开发

java实现zip压缩文件

2014-03-11 10:02 393 查看
现三种不错的方法:

1、jdk自带的包java.util.zip.ZipOutputStream,不足之处,文件(夹)名称带中文时,

出现乱码问题,实现代码如下:

/**

* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件

* @param sourceDir 如果是目录,eg:D:\\MyEclipse\\first\\testFile,则压缩目录下所有文件;

* 如果是文件,eg:D:\\MyEclipse\\first\\testFile\\aa.zip,则只压缩本文件

* @param zipFile 最后压缩的文件路径和名称,eg:D:\\MyEclipse\\first\\testFile\\aa.zip

*/

public File doZip(String sourceDir, String zipFilePath)

throws IOException {



File file = new File(sourceDir);

File zipFile = new File(zipFilePath);

ZipOutputStream zos = null;

try {

// 创建写出流操作

OutputStream os = new FileOutputStream(zipFile);

BufferedOutputStream bos = new BufferedOutputStream(os);

zos = new ZipOutputStream(bos);



String basePath = null;



// 获取目录

if(file.isDirectory()) {

basePath = file.getPath();

}else {

basePath = file.getParent();

}



zipFile(file, basePath, zos);

}finally {

if(zos != null) {

zos.closeEntry();

zos.close();

}

}



return zipFile;

}

/**

* @param source 源文件

* @param basePath

* @param zos

*/

private void zipFile(File source, String basePath, ZipOutputStream zos)

throws IOException {

File[] files = null;

if (source.isDirectory()) {

files = source.listFiles();

} else {

files = new File[1];

files[0] = source;

}



InputStream is = null;

String pathName;

byte[] buf = new byte[1024];

int length = 0;

try{

for(File file : files) {

if(file.isDirectory()) {

pathName = file.getPath().substring(basePath.length() + 1) + "/";

zos.putNextEntry(new ZipEntry(pathName));

zipFile(file, basePath, zos);

}else {

pathName = file.getPath().substring(basePath.length() + 1);

is = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(is);

zos.putNextEntry(new ZipEntry(pathName));

while ((length = bis.read(buf)) > 0) {

zos.write(buf, 0, length);

}

}

}

}finally {

if(is != null) {

is.close();

}

}

}

2、使用org.apache.tools.zip.ZipOutputStream,代码如下,
Java代码:

package net.szh.zip;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

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

public class ZipCompressor {
static final int BUFFER = 8192;

private File zipFile;

public ZipCompressor(String pathName) {
zipFile = new File(pathName);
}

public void compress(String srcPathName) {
File file = new File(srcPathName);
if (!file.exists())
throw new RuntimeException(srcPathName + "不存在!");
try {
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
String basedir = "";
compress(file, out, basedir);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void compress(File file, ZipOutputStream out, String basedir) {
/* 判断是目录还是文件 */
if (file.isDirectory()) {
System.out.println("压缩:" + basedir + file.getName());
this.compressDirectory(file, out, basedir);
} else {
System.out.println("压缩:" + basedir + file.getName());
this.compressFile(file, out, basedir);
}
}

/** 压缩一个目录 */
private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists())
return;

File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
/* 递归 */
compress(files[i], out, basedir + dir.getName() + "/");
}
}

/** 压缩一个文件 */
private void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
return;
}
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(file));
ZipEntry entry = new ZipEntry(basedir + file.getName());
out.putNextEntry(entry);
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
bis.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}


3、可以用ant中的org.apache.tools.ant.taskdefs.Zip来实现,更加简单。

Java代码

package net.szh.zip;

import java.io.File;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;

public class ZipCompressorByAnt {

private File zipFile;

public ZipCompressorByAnt(String pathName) {
zipFile = new File(pathName);
}

public void compress(String srcPathName) {
File srcdir = new File(srcPathName);
if (!srcdir.exists())
throw new RuntimeException(srcPathName + "不存在!");

Project prj = new Project();
Zip zip = new Zip();
zip.setProject(prj);
zip.setDestFile(zipFile);
FileSet fileSet = new FileSet();
fileSet.setProject(prj);
fileSet.setDir(srcdir);
//fileSet.setIncludes("**/*.java"); 包括哪些文件或文件夹 eg:zip.setIncludes("*.java");
//fileSet.setExcludes(...); 排除哪些文件或文件夹
zip.addFileset(fileSet);

zip.execute();
}
}

测试一下

Java代码

package net.szh.zip;

public class TestZip {
public static void main(String[] args) {
ZipCompressor zc = new ZipCompressor("E:\\szhzip.zip");
zc.compress("E:\\test");

ZipCompressorByAnt zca = new ZipCompressorByAnt("E:\\szhzipant.zip");
zca.compress("E:\\test");
}
}

转自http://ajava.org

http://ajava.org/article-1133-1.html

下面例子演示如何通过CheckedOutputStream和CheckedInputStream实现带验证的压缩、解压。
采用了Adler32算法,当然大家用CRC32算法也可以。
通过FilenameFilter方法,取得workspace/你的工程目录下的所有txt文件,但不包含子目录下的txt文件。
用途:主要用于需要确保压缩文件在压缩跟解压的无误操作,确保完全相同。

压缩例子代码:

package ajava.code.javase;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Adler32;

public class AjavaZipWithChecksum {
public static void main(String[] args) {
try {
String target = "ajavachecksum.zip";

FileOutputStream fos = new FileOutputStream(target);

//使用Adler32算法创建CheckedOutputStream校验输出流
CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));

int size = 0;
byte[] buffer = new byte[1024];

//
// Get all text files on the working folder.
//通过FilenameFilter取得所有txt文件
File dir = new File(".");
String[] files = dir.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.endsWith(".txt")) {
return true;
} else {
return false;
}
}
});

//压缩成ajavachecksum.zip
for (int i = 0; i < files.length; i++) {
System.out.println("压缩中...: " + files[i]);

FileInputStream fis = new FileInputStream(files[i]);
BufferedInputStream bis = new BufferedInputStream(fis, buffer.length);

ZipEntry zipEntry = new ZipEntry(files[i]);
zos.putNextEntry(zipEntry);

while ((size = fis.read(buffer, 0, buffer.length)) > 0) {
zos.write(buffer, 0, size);
}

zos.closeEntry();
fis.close();
}

zos.close();

System.out.println(" 校验码 : " + checksum.getChecksum().getValue());
} catch (IOException e) {
e.printStackTrace();
}
}
}

解压例子代码:
package ajava.code.javase;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.CheckedInputStream;
import java.util.zip.Adler32;

public class AjavaUnzipWithChecksum {
public static void main(String[] args) {
String zipname = "ajavachecksum.zip";

try {
FileInputStream fis = new FileInputStream(zipname);

//使用Adler32算法创建CheckedInputStream校验输出流
CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));
ZipEntry entry;

//解压ajavachecksum.zip
while ((entry = zis.getNextEntry()) != null) {
System.out.println("解压中....: " + entry.getName());

int size;
byte[] buffer = new byte[2048];

FileOutputStream fos = new FileOutputStream(entry.getName());
BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, size);
}
bos.flush();
bos.close();
}

zis.close();
fis.close();

System.out.println("校验码 = " + checksum.getChecksum().getValue());
} catch (IOException e) {
e.printStackTrace();
}
}
}

运行结果:
压缩中...: ajava11.txt
压缩中...: ajava.txt
校验码: 783456913

解压中....: ajava11.txt
解压中....: ajava.txt
校验码 = 783456913
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: