今天项目中遇到zip文件的压缩与解压问题。处理的是压缩和解压多级目录的问题。
废话不说把代码先贴上。
/**
* 创建ZIP文件
* @author 小马
* @creaetime 2013年12月9日 下午4:30:37
* @param sourcePath 文件或文件夹路径
* @param zipPath 生成的zip文件存在路径(包括文件名)
*/
public boolean createZip(String sourcePath, String zipPath) {
FileOutputStream fos = null;
ZipOutputStream zos = null;
File file = null;
boolean result = false;
try {
fos = new FileOutputStream(zipPath);
zos = new ZipOutputStream(fos);
file = new File(sourcePath);
result = writeZip(file, "", zos);
}
catch (FileNotFoundException e) {
result = false;
}
finally {
try {
if ( zos != null ) {
zos.close();
}
// del(sourcePath);
}
catch (IOException e) {
result = false;
}
}
return result;
}
/**
* @author 小马
* @creaetime 2013年12月9日 下午4:30:30
* @param file
* @param parentPath
* @param zos
*/
private boolean writeZip(File file, String parentPath, ZipOutputStream zos) {
boolean flag = true;
if ( file.exists() ) {
if ( file.isDirectory() ) {// 处理文件夹
parentPath += file.getName() + File.separator;
File[] files = file.listFiles();
for (File f : files) {
writeZip(f, parentPath, zos);
}
}
else {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
ZipEntry ze = new ZipEntry(parentPath + file.getName());
zos.putNextEntry(ze);
byte[] content = new byte[1024];
int len;
while ((len = fis.read(content)) != -1) {
zos.write(content, 0, len);
zos.flush();
}
}
catch (FileNotFoundException e) {
flag = false;
}
catch (IOException e) {
flag = false;
}
finally {
try {
if ( fis != null ) {
fis.close();
}
}
catch (IOException e) {
flag = false;
}
}
}
}
return flag;
}
以上是文件的压缩方法,需要用到java.util.zip.*这个包。但是处理解压过程中一直遇到中文乱码问题,就是当文件后者目录为中文的时候,程序要报异常。
最后在网上找到了解决的方法,代码如下:
/**
* 解压zip
* @author 小马
* @creaetime 2013年12月11日 下午5:20:50
* @param path 要解压文件
* @param savepath 文件解压后保存的目录
*/
public static void unZip(String path, String savepath) {
int count = -1;
File file = null;
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
//如果保存目录不存在则创建
if ( !new File(savepath).exists() ) {
new File(savepath).mkdir();
}
ZipFile zipFile = null;
try {
zipFile = new ZipFile(path, "gbk"); // 解决中文乱码问题
Enumeration<?> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
byte buf[] = new byte[1024];
ZipEntry entry = (ZipEntry) entries.nextElement();
String filename = entry.getName();
boolean ismkdir = false;
if ( filename.lastIndexOf("/") != -1 ) { // 检查此文件是否带有文件夹
ismkdir = true;
}
filename = savepath + filename;
if ( entry.isDirectory() ) { // 如果是文件夹先创建
file = new File(filename);
file.mkdirs();
continue;
}
file = new File(filename);
if ( !file.exists() ) { // 如果是目录先创建
if ( ismkdir ) {
new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); // 目录先创建
}
}
file.createNewFile(); // 创建文件
is = zipFile.getInputStream(entry);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, 1024);
while ((count = is.read(buf)) > -1) {
bos.write(buf, 0, count);
}
bos.flush();
bos.close();
fos.close();
is.close();
}
zipFile.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally {
try {
if ( bos != null ) {
bos.close();
}
if ( fos != null ) {
fos.close();
}
if ( is != null ) {
is.close();
}
if ( zipFile != null ) {
zipFile.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
解压方法,需要用com.springsource.org.apache.tools.ant.jar 这个包,问题解决。但是在解压原始的zip没有问题,在解压自己压缩的zip则报出找不到目录的错误,经过不断折腾,断点调试,发现 原始的zip中 String filename = entry.getName(); filename路径是以“/”隔开,而自己压缩的zip中,filename的路径是以“\”隔开,于是改成String filename = entry.getName().replace("\\", "/");问题就解决了。
发现压缩后的文件仍有乱码,于是压缩方法也用org.apache.tools.zip这个包。
上代码:
/**
* 压缩成zip
* @author 小马
* @creaetime 2013年12月12日 上午11:39:58
* @param zipFilep 压缩后的zip文件名
* @param path 压缩路径
* @throws Exception
*/
public boolean createZip(String path, String zipFilep) {
System.out.println("备份文件开始.....................");
File zipFile = new File(zipFilep);
boolean result = false;
ZipOutputStream out = null;
try {
if ( !zipFile.exists() ) {
zipFile.createNewFile();
}
out = new ZipOutputStream(new FileOutputStream(zipFile));
out.setEncoding("gbk");
write(out, path, "");
result = true;
}
catch (Exception e) {
result = false;
}finally{
if(out!=null){
try {
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("备份文件结束.....................");
return result;
}
/**
* 写压缩流
* @author 小马
* @creaetime 2013年12月12日 上午11:40:42
* @param out 压缩输出流
* @param path 压缩路径
* @param base 压缩式的基础目录 默认为空
* @throws Exception
*/
private void write(ZipOutputStream out, String path, String base) throws Exception {
File file = new File(path);
if ( file.isDirectory() ) {// 文件夹,递归
base = base.length() == 0 ? "" : base + File.separator;
File[] tempFiles = file.listFiles();
for (int i = 0; i < tempFiles.length; i++) {
write(out, tempFiles[i].getPath(), base + tempFiles[i].getName());
}
}
else {// 文件,压缩
byte[] buff = new byte[2048];
int bytesRead = -1;
ZipEntry entry = new ZipEntry(base);
out.putNextEntry(entry);
InputStream in = new BufferedInputStream(new FileInputStream(file));
while (-1 != (bytesRead = in.read(buff, 0, buff.length))) {
out.write(buff, 0, bytesRead);
}
in.close();
out.flush();
}
}