package com.cku.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class ZipUtils
{
	private static void _writeFile(ZipFile zipFile, ZipEntry entry, File file, byte[] buffer) throws Exception
	{
        BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		
		try
		{
            File parent = file.getParentFile();
            if(parent != null && (!parent.exists())){
                parent.mkdirs();
            }
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);           
            
            int count;
            while ((count = bis.read(buffer, 0, buffer.length)) != -1)
            {
                bos.write(buffer, 0, count);
            }
            bos.flush();
		}
		finally
		{
			if (bos != null) try { bos.close(); } catch (Exception e) {}
			if (bis != null) try { bis.close(); } catch (Exception e) {}
			if (fos != null) try { fos.close(); } catch (Exception e) {}
		}
	}
	
	public static void unzip(String folder, File zipF) throws Exception
	{
		ZipFile zipFile = new ZipFile(zipF);
		
		try
		{
	        Enumeration<? extends ZipEntry> emu = zipFile.entries();
	        byte data[] = new byte[1 << 14];
	        while (emu.hasMoreElements())
	        {
	            ZipEntry entry = (ZipEntry)emu.nextElement();
	            //会把目录作为一个file读出一次，所以只建立目录就可以，之下的文件还会被迭代到。
	            if (entry.isDirectory())
	            {
	            	File dir =  new File(folder, entry.getName());
	            	dir.mkdirs();
	            }
	            else
	            {
		            File file = new File(folder, entry.getName());
	            	_writeFile(zipFile, entry, file, data);		            
	            }
	        }
		}
		finally
		{
			zipFile.close();
		}
	}

	public static void zip(String zipFileName, File inputFile) throws Exception {
		FileOutputStream fos = new FileOutputStream(zipFileName);
		try
		{
			ZipOutputStream out = new ZipOutputStream(fos);
			BufferedOutputStream bo = new BufferedOutputStream(out);
			zip(out, inputFile, true, "", bo);
			out.close(); // 输出流关闭
		}
		finally
		{
			if (fos != null) try { fos.close(); } catch (Exception e) {}
		}
	}

	public static void zip(ZipOutputStream out, File f, boolean first, String base, BufferedOutputStream bo) throws Exception
	{
		if (f.isDirectory())
		{
			File[] fl = f.listFiles();
			if (fl.length == 0) {
				out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
				System.out.println(base + "/");
			}
			for (int i = 0; i < fl.length; i++)
			{
				if (first)
				{
					zip(out, fl[i], false, fl[i].getName(), bo); // 递归遍历子文件夹
				}
				else
				{
					zip(out, fl[i], false, base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
				}
			}
		} else {
			out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
			System.out.println(base);
			FileInputStream in = new FileInputStream(f);
			try
			{
				byte[] buffer = new byte[1 << 16];
				while (true)
				{
					int reads = in.read(buffer);
					if (reads < 0)
					{
						break;
					}
					
					bo.write(buffer, 0, reads);
				}
				bo.flush();
			}
			finally
			{
				if (in != null) try { in.close(); } catch (Exception e) {}
			}
		}
	}
}
