package com.ahzc.test;

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.io.InputStream;
import java.io.OutputStream;

import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Compress {

	/** 
	  * 功能:把 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 static 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 static 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) {//循环压缩文件夹下面的所有文件,知道zos.close的时候才算压缩完成
	    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();
	   }
	  }

	 }
	 
	 /**
		 * 解压到指定目录
		 * @param zipPath  压缩包目录
		 * @param descDir  生成文件保存目录
		 * 
		 */
		public static void unZipFiles(String zipPath,String descDir)throws IOException{
			unZipFiles(new File(zipPath), descDir);
		}
		/**
		 * 解压文件到指定目录
		 * @param zipFile
		 * @param descDir
		 * 
		 */
		@SuppressWarnings("rawtypes")
		public static void unZipFiles(File zipFile2,String descDir)throws IOException{
			 try {
		         //根据ZIP文件创建ZipFile对象
		         ZipFile zipFile = new ZipFile(zipFile2);
		            ZipEntry entry = null;
		            String entryName = null;
		            String targetFileName = null;
		            byte[] buffer = new byte[1024];
		            int bytes_read; 
		            //获取ZIP文件里所有的entry
		            Enumeration entrys = zipFile.entries();
		            //遍历所有entry
		            while (entrys.hasMoreElements()) {
		             entry = (ZipEntry)entrys.nextElement();
		             //获得entry的名字
		             entryName =  entry.getName();
		             targetFileName = descDir+File.separator+entryName;
		             if (entry.isDirectory()){
		              //  如果entry是一个目录,则创建目录
		              new File(targetFileName).mkdirs();
		              continue;
		             } else {
		              // 如果entry是一个文件,则创建父目录
		              new File(targetFileName).getParentFile().mkdirs();
		             }

		             //否则创建文件
		             File targetFile = new File(targetFileName);
		             System.out.println("创建文件:" + targetFile.getAbsolutePath());
		             //打开文件输出流
		             FileOutputStream os = new FileOutputStream(targetFile);
		             //从ZipFile对象中打开entry的输入流
		             InputStream  is = zipFile.getInputStream(entry);
		             while ((bytes_read = is.read(buffer)) != -1){
		              os.write(buffer, 0, bytes_read);
		             }
		             //关闭流
		             os.close( );
		             is.close( );
		            }
		            System.out.println("解压缩文件成功!");
		        } catch (IOException err) {
		            System.err.println("解压缩文件失败: " + err);
		        }
		}
}


/**
	 * 将zip压缩包解压到目标路径
	 * @param srcPath 目标路径
	 * @param zipPath zip压缩包路径
	 * @return boolean ret 是否解压成功
	 * */
	public static boolean swapZipToDirectory(String srcPath, String zipPath)
	{
		boolean ret = true;
		//解压缩目录zipPath这个文件到 SwapPath目录
		if (!new File(zipPath).exists()){
			ret = false;
			return ret;
		}
		
		if (!new File(srcPath).exists()){
			(new File(srcPath)).mkdirs();
		}
		
		Project proj = new Project();
		Expand expand = new Expand();
		expand.setProject(proj);
		expand.setTaskType("UNZIP");
		expand.setTaskName("UNZIP");
		expand.setEncoding("GBK");

		expand.setSrc(new File(zipPath));
		expand.setDest(new File(srcPath));
		expand.execute();
		
		return ret;
	}
	
	
	
/**
	 * 将目标路径压缩成zip压缩包
	 * @param srcPath 目标路径
	 * @param zipPath zip压缩包路径
	 * @return boolean ret 是否压缩成功
	 * */
	public static boolean swapDirectoryToZip(String srcPath, String zipPath)
	{
		//压缩目录xmldirPath下的所有文件
		boolean ret = true;
		File objFile = new File(srcPath);
		if (!objFile.exists()){
			ret = false;
			return ret;
		}
		Project objProject = new Project();
		FileSet objFileSet = new FileSet();
		objFileSet.setProject(objProject);
		// 判断是目录还是文件
		if (objFile.isDirectory()) {
			objFileSet.setDir(objFile);
		} else {
			objFileSet.setFile(objFile);
		}

		Zip objZip = new Zip();
		objZip.setProject(objProject);
		objZip.setDestFile(new File(zipPath));
		objZip.addFileset(objFileSet);
		objZip.setEncoding("GBK");
		objZip.execute();
		
		return ret;
	}