package com.kmall.common.utils.excel;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.zip.ZipInputStream;

/**
 * FileUtil. Simple file operation class.
 * 
 * @author BeanSoft
 */
public class FileUtil {
	/**
	 * The buffer.
	 */
	protected static byte buf[] = new byte[1024];

	/**
	 * 创建路径
	 * 
	 * @param path
	 * @return
	 */
	public static boolean mkdirs(String path) {
		try {
			File f = new File(path);
			if (!f.exists()) {
				f.mkdirs();
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * Read content from local file. FIXME How to judge UTF-8 and GBK, the correct code should be: FileReader fr = new FileReader(new
	 * InputStreamReader(fileName, "ENCODING")); Might let the user select the encoding would be a better idea. While reading UTF-8 files, the content
	 * is bad when saved out.
	 * 
	 * @param fileName
	 *            - local file name to read
	 * @return
	 * @throws Exception
	 */
	public static String readFileAsString(String fileName) throws Exception {
		String content = new String(readFileBinary(fileName));

		return content;
	}

	/**
	 * 读取文件并返回为给定字符集的字符串.
	 * 
	 * @param fileName
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	public static String readFileAsString(String fileName, String encoding) throws Exception {
		String content = new String(readFileBinary(fileName), encoding);

		return content;
	}

	/**
	 * 读取文件并返回为给定字符集的字符串.
	 *
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	public static String readFileAsString(InputStream in) throws IOException {
		String content = new String(readFileBinary(in));
		return content;
	}

	/**
	 * Read content from local file to binary byte array.
	 * 
	 * @param fileName
	 *            - local file name to read
	 * @return
	 * @throws Exception
	 */
	public static byte[] readFileBinary(String fileName) throws Exception {
		FileInputStream fin = new FileInputStream(fileName);

		return readFileBinary(fin);
	}

	/**
	 * 从输入流读取数据为二进制字节数组.
	 * 
	 * @param streamIn
	 * @return
	 * @throws IOException
	 */
	public static byte[] readFileBinary(InputStream streamIn) throws IOException {
		BufferedInputStream in = new BufferedInputStream(streamIn);

		ByteArrayOutputStream out = new ByteArrayOutputStream(10240);

		int len;
		while ((len = in.read(buf)) >= 0)
			out.write(buf, 0, len);
		in.close();

		return out.toByteArray();
	}

	/**
	 * Write string content to local file.
	 * 
	 * @param fileName
	 *            - local file name will write to
	 * @param content
	 *            String text
	 * @return true if success
	 * @throws IOException
	 */
	public static boolean writeFileString(String fileName, String content) throws IOException {
		FileWriter fout = new FileWriter(fileName);
		fout.write(content);
		fout.close();
		return true;
	}

	/**
	 * Write string content to local file using given character encoding.
	 * 
	 * @param fileName
	 *            - local file name will write to
	 * @param content
	 *            String text
	 * @param encoding
	 *            the encoding
	 * @return true if success
	 * @throws IOException
	 */
	public static boolean writeFileString(String fileName, String content, String encoding) throws IOException {
		OutputStreamWriter fout = new OutputStreamWriter(new FileOutputStream(fileName), encoding);

		fout.write(content);
		fout.close();
		return true;
	}

	/**
	 * Write binary byte array to local file.
	 * 
	 * @param fileName
	 *            - local file name will write to
	 * @param content
	 *            binary byte array
	 * @return true if success
	 * @throws IOException
	 */
	public static boolean writeFileBinary(String fileName, byte[] content) throws IOException {
		if (content == null || StringUtils.isEmpty(fileName)) {
			return false;
		}
		FileOutputStream fout = null;
		try {
			fout = new FileOutputStream(fileName);
			fout.write(content);
		} catch (IOException e) {
			throw e;
		} finally {
			if (fout != null) {
				try {
					fout.close();
				} catch (IOException e) {
				}
			}
		}
		return true;
	}

	/**
	 * 检查文件名是否合法.文件名字不能包含字符\/:*?"<>|
	 *
	 *            ,不包含路径
	 * @return boolean is valid file name
	 */
	public static boolean isValidFileName(String fileName) {
		boolean isValid = true;
		String errChar = "\\/:*?\"<>|"; //
		if (fileName == null || fileName.length() == 0) {
			isValid = false;
		} else {
			for (int i = 0; i < errChar.length(); i++) {
				if (fileName.indexOf(errChar.charAt(i)) != -1) {
					isValid = false;
					break;
				}
			}
		}
		return isValid;
	}

	/**
	 * 把非法文件名转换为合法文件名.
	 * 
	 * @param fileName
	 * @return
	 */
	public static String replaceInvalidFileChars(String fileName) {
		StringBuffer out = new StringBuffer();

		for (int i = 0; i < fileName.length(); i++) {
			char ch = fileName.charAt(i);
			// Replace invlid chars: \\/:*?\"<>|
			switch (ch) {
			case '\\':
			case '/':
			case ':':
			case '*':
			case '?':
			case '\"':
			case '<':
			case '>':
			case '|':
				out.append('_');
				break;
			default:
				out.append(ch);
			}
		}

		return out.toString();
	}

	/**
	 * Convert a given file name to a URL(URI) string.
	 * 
	 * @param fileName
	 *            - the file to parse
	 * @return - URL string
	 */
	public static String filePathToURL(String fileName) {
		String fileUrl = new File(fileName).toURI().toString();
		return fileUrl;
	}

	/**
	 * Write string content to local file.
	 * 
	 * @param fileName
	 *            - local file name will write to
	 * @param content
	 *            String text
	 * @return true if success
	 * @throws IOException
	 */
	public static boolean appendFileString(String fileName, String content) throws IOException {
		OutputStreamWriter fout = new OutputStreamWriter(new FileOutputStream(fileName, true), "UTF-8");
		fout.write(content);
		fout.close();
		return true;
	}

	/**
	 * 根据文件路径和文件名获取文件名
	 * 
	 * @param filePathAndName
	 * @return
	 */
	public static String getFileName(String filePathAndName) {
		int a = filePathAndName.lastIndexOf("\\");
		int b = filePathAndName.lastIndexOf("/");
		String fileName = filePathAndName.substring((a > b ? a : b) + 1, filePathAndName.length());
		return fileName;
	}

	public static boolean copy(String fileFrom, String fileTo) {
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream(fileFrom);
			out = new FileOutputStream(fileTo);
			byte[] bt = new byte[1024];
			int count;
			while ((count = in.read(bt)) > 0) {
				out.write(bt, 0, count);
			}
			return true;
		} catch (IOException ex) {
			ex.printStackTrace();
			return false;
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 读取输入流
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		//创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		//每次读取的字符串长度，如果为-1，代表全部读取完毕
		int len = 0;
		//读取一定数量的字节从输入流并存入缓冲区 buffer
		while ((len = inStream.read(buffer)) != -1) {
			//用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
			//写 len字节指定字节数组中的偏移 off开始到输出流。
			outStream.write(buffer, 0, len);
		}
		//关闭输入流
		inStream.close();
		//把outStream里的数据写入内存
		return outStream.toByteArray();
	}


	/**
	 * 读取输入流
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] readZipInputStream(ZipInputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		//创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		//每次读取的字符串长度，如果为-1，代表全部读取完毕
		int len = 0;
		//读取一定数量的字节从输入流并存入缓冲区 buffer
		while ((len = inStream.read(buffer)) != -1) {
			//用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
			//写 len字节指定字节数组中的偏移 off开始到输出流。
			outStream.write(buffer, 0, len);
		}
		//关闭当前的压缩条目并将流用于读取下一个条目。
		inStream.closeEntry();
		//把outStream里的数据写入内存
		return outStream.toByteArray();
	}




	//删除指定文件夹下所有文件
//param path 文件夹完整绝对路径
	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
				delFolder(path + "/" + tempList[i]);//再删除空文件夹
				flag = true;
			}
		}
		return flag;
	}


	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); //删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			File myFilePath = new File(filePath);
			myFilePath.delete(); //删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}