package com.ylcm.sys.common;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.innosystec.unrar.Archive;
import de.innosystec.unrar.NativeStorage;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.rarfile.FileHeader;

/**
 * RAR文件解析工具类
* <p>Title: RarUtil.java</p>
* <p>Description: TODO</p> 
* @author liushiming
* @date 2017-7-19
 */
public class RarUtil {

	public static final String SEPARATOR = "/";

	private static List<File> list = new ArrayList<File>();
	
	private static final Log log = LogFactory.getLog(RarUtil.class);
	/**
	 * 解压指定RAR文件到当前文件夹
	 * 
	 * @param srcRar
	 *            指定解压
	 * @param password
	 *            压缩文件时设定的密码
	 * @throws IOException
	 */
	public static void unrar(String srcRar, String password) throws IOException {
		unrar(srcRar, null, password);
	}

	/**
	 * 解压指定的RAR压缩文件到指定的目录中
	 * 
	 * @param srcRar
	 *            指定的RAR压缩文件
	 * @param destPath
	 *            指定解压到的目录
	 * @param password
	 *            压缩文件时设定的密码
	 * @throws IOException
	 */
	public static void unrar(String srcRar, String destPath, String password)
			throws IOException {
		File srcFile = new File(srcRar);
		if (!srcFile.exists()) {
			return;
		}
		if (null == destPath || destPath.length() == 0) {
			unrar(srcFile, srcFile.getParent(), password);
			return;
		}
		unrar(srcFile, destPath, password);
	}

	/**
	 * 解压指定的RAR压缩文件到指定的目录中
	 * 
	 * @param urlSrcRar
	 *            RAR网络地址
	 * @param destPath
	 *            指定解压到的目录
	 * @param password
	 *            压缩文件时设定的密码
	 * @return 解压后的目录
	 * @throws IOException
	 */
	public static String unUrlRar(String urlSrcRar, String destPath,
			String folder, String password) throws IOException {
		File srcFile = null;
		URL httpurl = new URL(urlSrcRar);
		srcFile = new File(destPath + SEPARATOR + folder + ".rar");
		FileUtils.copyURLToFile(httpurl, srcFile);
		if (!srcFile.exists()) {
			throw new IOException("目标文件找不到.");
		}
		if (null == destPath || destPath.length() == 0) {
			unrar(srcFile, srcFile.getParent(), password);
		}
		unrar(srcFile, destPath + SEPARATOR + folder, password);
		return destPath + SEPARATOR + folder;
	}

	/**
	 * 解压指定RAR文件到当前文件夹
	 * 
	 * @param srcRarFile
	 *            解压文件
	 * @param password
	 *            压缩文件时设定的密码
	 * @throws IOException
	 */
	public static void unrar(File srcRarFile, String password)
			throws IOException {
		if (null == srcRarFile || !srcRarFile.exists()) {
			throw new IOException("指定文件不存在.");
		}
		unrar(srcRarFile, srcRarFile.getParent(), password);
	}

	/**
	 * 解压指定RAR文件到指定的路径
	 * 
	 * @param srcRarFile
	 *            需要解压RAR文件
	 * @param destPath
	 *            指定解压路径
	 * @param password
	 *            压缩文件时设定的密码
	 * @throws IOException
	 */
	public static void unrar(File srcRarFile, String destPath, String password)
			throws IOException {
		if (null == srcRarFile || !srcRarFile.exists()) {
			throw new IOException("指定压缩文件不存在.");
		}
		if (!destPath.endsWith(SEPARATOR)) {
			destPath += SEPARATOR;
		}
		Archive archive = null;
		OutputStream unOut = null;
		try {
			archive = new Archive(new NativeStorage(srcRarFile));
			FileHeader fileHeader = archive.nextFileHeader();
			while (null != fileHeader) {
				System.out.println("null != fileHeader");
				if (!fileHeader.isDirectory()) {
					// 1 根据不同的操作系统拿到相应的 destDirName 和 destFileName
					String destFileName = "";
					String destDirName = "";
					if (SEPARATOR.equals("/")) { // 非windows系统
						String fileName=  fileHeader.getFileNameW().trim();
						if(!existZH(fileName)){  
							destFileName = (destPath +  fileHeader.getFileNameString())
									.replaceAll("\\\\", "/");
							log.info("destFileName" + destFileName+"---"+"fileHeader.getFileNameString()" + fileHeader.getFileNameString());
							destDirName = destFileName.substring(0,
									destFileName.lastIndexOf("/"));
		                } else {
		                	destFileName = (destPath +  fileHeader.getFileNameW())
									.replaceAll("\\\\", "/");
							log.info("destFileName" + destFileName+"---"+"fileHeader.getFileNameString()" + fileHeader.getFileNameW());
							destDirName = destFileName.substring(0,
									destFileName.lastIndexOf("/"));
		                }
					} else { // windows系统
						destFileName = (destPath + fileHeader.getFileNameString()).replaceAll("/", "\\\\");
						destDirName = destFileName.substring(0,destFileName.lastIndexOf("\\"));
					}
					// 2创建文件夹
					File dir = new File(destDirName);
					if (!dir.exists() || !dir.isDirectory()) {
						dir.mkdirs();
					}
					// 抽取压缩文件
					unOut = new FileOutputStream(new File(destFileName));
					archive.extractFile(fileHeader, unOut);
					unOut.flush();
					unOut.close();
				}
				fileHeader = archive.nextFileHeader();
			}
			archive.close();
		} catch (RarException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(unOut);
		}
	}
	
	
	public static boolean existZH(String str) {  
	    String regEx = "[\\u4e00-\\u9fa5]";  
	    Pattern p = Pattern.compile(regEx);  
	    Matcher m = p.matcher(str);  
	    while (m.find()) {  
	        return true;  
	    }  
	    return false;  
	}
	
	/**
	 * 读取某个文件夹下的所有文件
	 */
	public static List<File> readfile(String filepath) throws FileNotFoundException, IOException {
		try {
			File file = new File(filepath);
			if (!file.isDirectory()) {
				list.add(file);
			} else if (file.isDirectory()) {
				String[] filelist = file.list();
				for (int i = 0; i < filelist.length; i++) {
					File readfile = new File(filepath + SEPARATOR + filelist[i]);
					if (!readfile.isDirectory()) {
						list.add(readfile);
					} else if (readfile.isDirectory()) {
						//文件夹，继续访问下一级目录
						readfile(filepath + SEPARATOR + filelist[i]);
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 删除某个文件夹下的所有文件夹和文件
	 */
	public static boolean deletefile(String delpath) throws FileNotFoundException, IOException {
		try {
			File file = new File(delpath);
			if (!file.isDirectory()) {
				file.delete();
			} else if (file.isDirectory()) {
				String[] filelist = file.list();
				for (int i = 0; i < filelist.length; i++) {
					File delfile = new File(delpath + SEPARATOR + filelist[i]);
					if (!delfile.isDirectory()) {
						delfile.delete();
					} else if (delfile.isDirectory()) {
						deletefile(delpath + SEPARATOR + filelist[i]);
					}
				}
				file.delete();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return true;
	}

	public static void main(String[] args) throws IOException {
		String zipFilePath = "C:\\Users\\Administrator\\Desktop\\ppgl.rar";

		String destDir = "C:\\Users\\Administrator\\Desktop\\11";

	    RarUtil.unrar(zipFilePath, destDir, null);
	    
//		List<File> list = RarUtil.readfile("C:\\Users\\Administrator\\Desktop\\11\\11");
//		for(File file : list )
//			System.out.println(file.getName());
	}

}