/*
 * 文件名:ZipTool.java
 * 创建时间:2012-2-22 16:21:04
 * 作者:Leoly
 * 版权:Copyright(c) 2012
 */
package com.honey.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * 此工具类可提供压缩 功能
 * 
 * @author Leoly
 * @version v1.0, 2012-2-22
 */
public class ZipTool { 
	// 输入的压缩文件已经存在于该路径中
	public static final int EXIST_ZIPFILE = 4;

	// 操作成功
	public static final int ZIPOPTION_SUCCESS = 3;

	// 操作失败
	public static final int ZIPOPTION_FAIL = 5;

	

	/**
	 * 压缩文件方法,可以压缩多个文件或者目录
	 * 
	 * @param newZipPath
	 *            String 生成压缩文件的路径
	 * @param wantZipPaths
	 *            String[] 需要压缩的文件条目
	 */
	public static int zip(String newZipPath, File[] wantZipFile) {
		// 生成压缩文件的路径已经存在时,返回文件已经存在的状态
		File file = new File(newZipPath);
		if (file.exists()) {
			return EXIST_ZIPFILE;
		}

		// 不存在时,创建用户输入的目录结构
		String filePath = file.getAbsolutePath();
		String basePath = filePath.substring(0, filePath.lastIndexOf(File.separator));
		File dirFile = new File(basePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		ZipOutputStream zos = null;
		try {
			// 生成压缩文件
			if (!file.exists()) {
				file.createNewFile();
			}

			// 打开压缩文件输出流,准备把待压缩的文件写入
			FileOutputStream fos = new FileOutputStream(file);
			zos = new ZipOutputStream(fos);
			System.out.println("ZOS 1:"+zos);
			for (File tempFile : wantZipFile) {
				if (!tempFile.exists()) {
					continue;
				}

				// 进行压缩文件
				zipEachFile(zos, tempFile, "");
			}
		} catch (IOException ie) {
			file.delete();
			return ZIPOPTION_FAIL;
		} finally {
			try {
				System.out.println("ZOS 2:"+zos);
				if(zos!=null){
					zos.close();
				}
			} catch (IOException e) {
				file.delete();
				e.printStackTrace();
				return ZIPOPTION_FAIL;
	 		}
		}

		return ZIPOPTION_SUCCESS;
	}

	/**
	 * 压缩某个文件或文件夹 压缩文件方法,可以压缩多个文件或者目录
	 * 
	 * @param zos
	 *            ZipOutputStream 压缩文件的输出流
	 * @param zipFile
	 *            File 需要压缩的文件或文件夹
	 * @param baseDir
	 *            String 压缩文件夹中的递归路径,使用时直接传入空值即可
	 */
	private static void zipEachFile(ZipOutputStream zos, File zipFile, String baseDir) {
		ZipEntry entry = null;

		// 如果需要压缩的是一个目录,由扫描该目录下的文件,并递归调用本方法进行压缩处理
		if (zipFile.isDirectory()) {
			// 压缩文件中的递归路径,记录了压缩文件中的文件夹路径
			baseDir = baseDir + zipFile.getName() + File.separator;
			File[] tempFiles = zipFile.listFiles();
			for (File tempFile : tempFiles) {
				zipEachFile(zos, tempFile, baseDir);
			}
		}

		// 不是文件夹时,使用文件输入流和压缩文件输出流把文件写入压缩文件中
		else {
			FileInputStream fis = null;
			try {
				entry = new ZipEntry(baseDir + zipFile.getName());
				zos.putNextEntry(entry);
				fis = new FileInputStream(zipFile);
				byte[] buffer = new byte[1024 * 5];
				int readSize = 0;
				while ((readSize = fis.read(buffer)) > 0) {
					zos.write(buffer, 0, readSize);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					fis.close();
					zos.closeEntry();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
